JSON Schema Core
JSONにプログラミング言語的なclassや構造体(struct)、配列(array)、整数、文字列のような型と並びの組み合わせを意味づけ定義してデータ構造を制約するもの
Javaのソースやclassに相当する部分(変数、型のみで実行コードはない)を書くことで、Validationツールで検証できるようになる、注釈(コメント)も書ける
型が決まるので他の言語との変換なども自動化しやすい
JSONの構造に対してBNF的なものをJSONで書いて適応したもの、にできるか
JSON Schema自体もJSONで記述する、というのは最後に知ればいい情報か
JSON Schema
https://json-schema.org/specification
JSON Schema Core
https://github.com/json-schema-org/json-schema-spec/blob/main/specs/jsonschema-core.md
https://json-schema.org/draft/2020-12/json-schema-core
https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-01
https://qiita.com/kyoh86/items/e7de290e9a0e989fcc14 draft 4.0
JSON Schema Validation
Relative JSON Pointers
draftの外れた? バージョンは2つぐらいある まだドラフト?
2020-12
2019-09
スキーマ記述言語
RFC 8927 JSON Type Definition
のようなものもある
https://json-schema.org/draft/2020-12/json-schema-core
JSONスキーマ: JSONドキュメントを記述するためのメディアタイプ
概要
JSON Schemaは、JSON dataの構造を記述するためのJSONベースのフォーマットであるメディアタイプ「application/schema+json」を定義します。JSON Schemaは、JSONドキュメントの外観、そこから情報を抽出する方法、そしてJSONドキュメントとやり取りする方法を明示します。「application/schema-instance+json」メディアタイプは、「application/json」ドキュメントで提供できる機能に加えて、「application/schema+json」との豊富な統合機能を提供します。
読者への注意
このドラフトの課題リストは、https://github.com/json-schema-org/json-schema-spec/issues で確認できます。
詳細については、https://json-schema.org/ を参照してください。
フィードバックを提供するには、この課題トラッカー、ホームページに記載されている連絡方法、またはドキュメント編集者にメールでお問い合わせください。
このメモの状態 Status of This Memo
このインターネットドラフトは、BCP 78およびBCP 79の規定に完全に準拠して提出されています。
インターネットドラフトは、インターネット技術タスクフォース(IETF)の作業文書です。他の団体も作業文書をインターネットドラフトとして配布する場合があります。最新のインターネットドラフトの一覧は、https://datatracker.ietf.org/drafts/current/ をご覧ください。
インターネットドラフトは、最長6か月間有効なドラフト文書であり、いつでも更新、置き換え、または他の文書によって廃止される可能性があります。インターネットドラフトを参考資料として使用したり、「作業中」という表現以外で引用したりすることは不適切です。
このインターネットドラフトは、2022年12月18日に期限切れとなります。
著作権表示 Copyright Notice
Copyright (c) 2022 IETF Trustおよび本書の著者として特定されている人物。All rights reserved.
本文書は、BCP 78およびIETF TrustのIETF文書に関する法的規定( https://trustee.ietf.org/license-info )の対象となります。これらの規定には、本文書に関するお客様の権利と制限が記載されているため、これらの規定をよくお読みください。本文書から抽出されたコードコンポーネントには、Trustの法的規定のセクション4.eに記載されている改訂BSDライセンスのテキストが含まれている必要があり、改訂BSDライセンスに記載されているように、無保証で提供されます。
1. はじめに Introduction
JSON Schemaは、JSONデータの構造を定義するためのJSONメディアタイプです。JSON Schemaは、JSONデータの検証、ドキュメント化、ハイパーリンクナビゲーション、およびインタラクション制御を定義することを目的としています。
本仕様は、参照による別のJSON Schemaの指定、JSON Schema参照の逆参照、使用されている方言の指定、方言の語彙要件の指定、および期待される出力の定義を含む、JSON Schemaのコア用語とメカニズムを定義します。
他の仕様では、検証、リンク、注釈、ナビゲーション、およびインタラクションに関するアサーションを実行する語彙が定義されています。
2. 規約と用語 Conventions and Terminology
本文書におけるキーワード「MUST(しなければならない)」、「MUST NOT(してはならない)」、「REQUIRED(必須)」、「SHALL(するべきである)」、「SHALL NOT(するべきではない)」、「SHOULD(すべきである)」、「SHOULD NOT(すべきではない)」、「RECOMMENDED(推奨される)」、「MAY(してもよい)」、「OPTIONAL(選択できる)」は、RFC 2119 RFC 2119 に記述されているとおりに解釈されます。
このドキュメントにおける「JSON」、「JSONテキスト」、「JSON値」、「メンバー」、「要素」、「オブジェクト」、「配列」、「数値」、「文字列」、「ブール値」、「true」、「false」、「null」という用語は、RFC 8259 RFC 8259 の定義に従って解釈されます。
3. 概要 Overview
このドキュメントでは、JSONデータを記述するためのJSON Schemaを識別するための新しいメディアタイプ「application/schema+json」を提案します。また、追加の統合機能を提供するために、オプションのメディアタイプ「application/schema-instance+json」も提案します。JSON Schema自体はJSONドキュメントです。このドキュメントおよび関連仕様では、作成者がJSONデータを複数の方法で記述できるようにキーワードを定義しています。
JSON Schemaは、キーワードを使用してJSONインスタンスに制約をアサートしたり、追加情報を注釈として付与したりします。追加のキーワードは、より複雑なJSONデータ構造に、または何らかの条件に基づいてアサーションや注釈を適用するために使用されます。
再利用を容易にするために、キーワードは語彙(vocabularies)として整理できます。語彙は、キーワードのリストとその構文および意味から構成されます。方言(dialect)は、語彙の集合と、メタスキーマで識別されるそれらの必須サポートとして定義されます。
JSON Schemaは、追加の語彙を定義することによって、またはより非公式には語彙の外部で追加のキーワードを定義することによって拡張できます。認識されない個々のキーワードは、単にアノテーションとして値が収集されますが、認識されない語彙に関する動作は、どの語彙が使用されているかを宣言することで制御できます。
このドキュメントでは、あらゆる実装でサポートされなければならないコア語彙(core vocabulary)を定義します。この語彙は無効化できません。この語彙のキーワードには、必須であることを強調するために、それぞれに「$」という接頭辞が付けられています。この語彙は「application/schema+json」メディアタイプの機能に不可欠であり、他の語彙の読み込みをブートストラップするために使用されます。
さらに、このドキュメントでは、サブスキーマを条件付きで適用するためのキーワード、およびオブジェクトと配列の内容にサブスキーマを適用するためのキーワードの推奨語彙(RECOMMENDED vocabulary)を定義します。この語彙、またはこれに非常に類似した語彙のいずれかは、アサーション検証、アノテーション、またはその両方を目的とした非自明なJSONインスタンスのスキーマを記述するために必要です。必須のコア語彙の一部ではありませんが、相互運用性を最大限に高めるために、この追加語彙はこのドキュメントに含まれており、その使用を強く推奨します。
構造検証やハイパーメディアアノテーションなどの目的のための追加の語彙は、他のドキュメントで定義されています。これらの他のドキュメントはそれぞれ、そのドキュメントの目的に合ったスキーマを記述するために必要な標準的な語彙セットを収集した方言を定義しています。
4. 定義 Definitions
4.1. JSON文書 JSON Document
JSON文書は、application/jsonメディアタイプで記述される情報リソース(オクテット列)です。
JSON Schemaでは、「JSON document」(JSON文書)、「JSON text」(JSONテキスト)、「JSON value」(JSON値)という用語は、定義するデータモデルのため互換性があります。
JSON SchemaはJSON文書に対してのみ定義されます。ただし、JSON Schemaデータモデルに従って解析または処理できる文書またはメモリ構造であれば、CBOR RFC 7049などのメディアタイプを含め、JSON Schemaに基づいて解釈できます。
4.2. インスタンス Instance
スキーマが適用されるJSON文書は「instance」(インスタンス)と呼ばれます。
JSON Schemaは、「application/json」または互換性のある文書(構造化構文サフィックス「+json」を持つメディアタイプを含む)に対して定義されます。
これらのうち、本仕様では、URI内のフラグメントの扱いを定義する「application/schema-instance+json」メディアタイプを定義します。
4.2.1. インスタンスデータモデル Instance Data Model
JSON Schemaは、データモデルに従って文書を解釈します。このデータモデルに従って解釈されたJSON値は「インスタンス」と呼ばれます。
インスタンスは6つのプリミティブ型のいずれかを持ち、その型に応じて取り得る値の範囲は以下となります。
null: JSONの「null」値
boolean: JSONの「true」または「false」値から得られる「true」または「false」値
object: JSONの「object」値から得られる、文字列をインスタンスにマッピングする順序なしのプロパティセット
array: JSONの「array」値から得られる、インスタンスの順序付きリスト
number: JSONの「number」値から得られる、任意精度の10進数値
string: JSONの「string」値から得られる、Unicodeコードポイントの文字列
したがって、データモデル内で等しい数値の異なる語彙表現を含む、空白や書式設定に関する事項は、JSON Schemaの対象外です。このような語彙表現の違いを扱おうとするJSON Schema 語彙(セクション8.1)は、元のJSON表現のUnicode文字が利用可能であることに依存するのではなく、データモデル内でフォーマットされた文字列を正確に解釈するためのキーワードを定義するべきです(SHOULD)。
オブジェクトは同じキーを持つ2つのプロパティを持つことはできないため、JSON文書が単一のオブジェクト内で同じキーを持つ2つのプロパティを定義しようとした場合の動作は未定義です。
JSON Schema語彙は、独自の拡張型システムを自由に定義できることに注意してください。これは、ここで定義されているコアデータモデルの型と混同しないでください。例えば、「integer」は語彙がキーワードの値として定義するのに適した型ですが、データモデルでは整数とその他の数値を区別しません。
4.2.2. インスタンスの等価性 Instance Equality
2つのJSONインスタンスは、データモデルに従って同じ型で同じ値を持つ場合にのみ、等しいとされます。具体的には、以下の条件を満たすことを意味します。
両方ともnullである。または
両方ともtrueである。または
両方ともfalseである。または
両方とも文字列であり、コードポイントごとに同じである。または
両方とも数値であり、数値ごとに同じである。または
両方とも配列であり、項目ごとに等しい値を持つ。または
両方ともオブジェクトであり、一方のプロパティには、他方のプロパティとキーが等しいプロパティが1つだけ存在し、そのプロパティの値が等しい。
この定義から、配列は同じ長さでなければならないこと、オブジェクトは同じメンバー数を持つ必要があること、オブジェクト内のプロパティは順序付けされていないこと、同じキーを持つ複数のプロパティを定義することはできないこと、そして単なるフォーマットの違い(インデント、カンマの配置、末尾のゼロ)は重要ではないことが示唆されます。
4.2.3. JSON以外のインスタンス Non-JSON Instances
JSON Schema データモデルのスーパーセットでJSON Schemaを使用することが可能です。この場合、インスタンスは6つのJSONデータ型のいずれにも該当しません。
この場合もアノテーションは適用されますが、ほとんどの検証キーワードは常に合格か不合格かのどちらかになるため、役に立ちません。
カスタム語彙では、コアデータモデルのスーパーセットのサポートを定義できます。スキーマ自体は、このスーパーセットでのみ表現できる場合があります。例えば、「const」キーワードを使用する場合などです。
4.3. JSON Schema文書 JSON Schema Documents
JSON Schema 文書(または単にSchema, スキーマ)は、インスタンスを記述するために使用されるJSON文書です。スキーマ自体はインスタンスとして解釈できますが、メディアタイプ(media type)は常に「application/schema-instance+json」ではなく「application/schema+json」にする必要があります。「application/schema+json」メディアタイプは、「application/schema-instance+json」が提供するフラグメント識別子の構文とセマンティクスのスーパーセットを提供するために定義されています。
JSON Schemaは、オブジェクトまたはブール値でなければなりません。
4.3.1. JSON Schemaオブジェクトとキーワード
インスタンスに適用されるオブジェクトプロパティは、キーワードまたはスキーマキーワードと呼ばれます。大まかに言えば、キーワードは以下の5つのカテゴリに分類されます。
identifiers(識別子): スキーマのURIを設定したり、ベースURIの決定方法を変更したりすることで、スキーマの識別を制御します。
assertions(アサーション:主張・断言): インスタンスに適用された際に boolean値の結果を生成します。
annotation(アノテーション:注釈): アプリケーションで使用するために、インスタンスに情報を付加します。
applicators(アプリケータ): インスタンス内の特定の場所に1つ以上のサブスキーマを適用し、それらの結果を結合または変更します。
reserved locations(予約済み場所): 結果に直接影響を与えませんが、相互運用性を確保するために特定の目的のために場所を予約します。
キーワードは複数のカテゴリに分類される場合がありますが、アプリケータはサブスキーマの結果に基づいてアサーション結果のみを生成する必要があります(SHOULD)。サブスキーマとは独立して追加の制約を定義してはなりません。
同じスキーマオブジェクト内のプロパティであるキーワードは、隣接キーワード(adjacent keywords)と呼ばれます。
拡張キーワード(Extension keywords)(このドキュメントおよびその関連ドキュメントの外で定義されているキーワード)は、他の動作も自由に定義できます。
JSON Schemaには、スキーマキーワードではないプロパティを含めることができます(MAY)。不明なキーワードは、キーワードの値がアノテーションの値となるアノテーションとして扱う必要があります(SHOULD)。
空のスキーマとは、プロパティを持たない、または不明なプロパティのみを持つJSON Schemaです。
4.3.2. Boolean JSON Schemas
booleanスキーマ値「true」と「false」は、インスタンス値に関わらず、常にアサーション結果(assertion results)として生成される単純なスキーマです。アノテーション結果(annotation results)は生成しません。
これらのbooleanスキーマは、スキーマ作成者の意図を明確にし、スキーマ処理の最適化を容易にするために存在します。これらは、以下のスキーマオブジェクトと同様に動作します(「not」はこのドキュメントで定義されているサブスキーマ適用語彙の一部です)。
true: 空のスキーマが{}であるかのように、常に検証に合格します。
false: スキーマが{ "not": {} }であるかのように、常に検証に失敗します。
空のスキーマオブジェクトは明確ですが、「false」スキーマに相当するものは多数存在します。boolean値を使用すると、人間の読者と実装の両方に意図が明確になります。
4.3.3. スキーマ語彙 Schema Vocabularies
スキーマ語彙(スキーマボキャブラリまたは単に語彙)は、キーワード、その構文、および意味の集合です。語彙は通常、特定の目的を中心に構成されます。JSON Schemaの様々な用途、例えば検証、ハイパーメディア、ユーザーインターフェース生成などには、それぞれ異なる語彙セットが用いられます。
語彙はJSON Schemaにおける再利用の主要な単位です。スキーマ作成者は、スキーマを処理するためにどの語彙が必須かオプションかを指定できます。語彙はメタスキーマ内のURIで識別されるため、汎用的な実装では、これまで知られていなかった語彙をサポートするための拡張機能を読み込むことができます。キーワードは語彙の外部でもサポートできますが、個々のキーワードの使用状況を示す類似のメカニズムはありません。
スキーマ語彙は、対象読者や相互運用性の期待に応じて、非公式な記述から標準提案まで、様々な方法で定義できます。特に、非公開組織における語彙の利用を促進するため、語彙仕様は使用範囲外では公開する必要はありません。
4.3.4. メタスキーマ Meta-Schemas
スキーマ自体がスキーマを記述するスキーマは、メタスキーマと呼ばれます。メタスキーマは、JSON Schemaを検証し、どの語彙を使用しているかを指定するために使用されます。
通常、メタスキーマは語彙セットを指定し、それらの語彙の構文に準拠するスキーマを検証します。しかし、メタスキーマと語彙は分離されており、メタスキーマは語彙の仕様で要求されるよりも厳密に、あるいはより緩くスキーマへの適合性を検証できます。メタスキーマは、正式な語彙に含まれない追加のキーワードを記述し、検証することもできます。
4.3.5.ルートスキーマ、サブスキーマ、およびリソース Root Schema and Subschemas and Resources
JSON Schemaリソースとは、絶対(absolute) URI RFC 3986 によって 正準的(canonically) RFC 6596 に識別されるスキーマです。スキーマリソースは、結果として得られるセカンダリリソース(URI RFC 3986 のセクション3.5で定義)がプライマリリソースと同一である場合、フラグメントを含むURIを含むURIで識別されることもあります。これは、空のフラグメントの場合、またはあるスキーマリソースが別のスキーマリソースに埋め込まれている場合に発生する可能性があります。このようなフラグメントを含むURIは非正準とみなされます。
ルートスキーマとは、対象となるJSON文書全体を構成するスキーマです。ルートスキーマは常にスキーマリソースであり、URIはセクション9.1.1で説明されているように決定されます。
別の形式のスキーマを埋め込む文書は、この意味ではルートスキーマリソースを持たないことに注意してください。このような用法がJSONスキーマ文書およびリソースの概念とどのように適合するかについては、今後のドラフトで明確にされる予定です。
一部のキーワードはスキーマ自体を受け取り、JSON Schemaをネストできます。
code:nested.json
{
"title": "root",
"items": {
"title": "array item"
}
}
このサンプルドキュメントでは、「array item」というtitleのスキーマがサブスキーマであり、「root」というtitleのスキーマがルートスキーマです。
ルートスキーマと同様に、サブスキーマは object または boolean のいずれかです。
セクション8.2.1で説明したように、JSON Schemaドキュメントには複数のJSON Schemaリソースを含めることができます。修飾なしで使用される「root schema」という用語は、ドキュメントのルートスキーマを指します。場合によっては、リソースのルートスキーマについて説明します。リソースのルートスキーマは、その最上位のスキーマオブジェクトであり、リソースがスタンドアロンのJSON Schemaドキュメントに抽出される場合は、ドキュメントのルートスキーマにもなります。
複数のスキーマリソースが埋め込まれているか、参照でリンクされているかに関係なく、それらは同じ方法で処理され、同じ動作が可能です。
5. フラグメント識別子 Fragment Identifiers
RFC 6839 RFC 6839 のセクション 3.1 に従い、あらゆる +json メディアタイプに指定されるフラグメント識別子の構文とセマンティクスは、「application/json」に指定されているものと同じである必要があります。(本文書の公開時点では、「application/json」にフラグメント識別子の構文は定義されていません。)
さらに、「application/schema+json」メディアタイプは、プレーンネームと JSON Pointerの 2 つのフラグメント識別子構造をサポートします。「application/schema-instance+json」メディアタイプは、JSON Pointerの 1 つのフラグメント識別子構造をサポートします。
JSON Pointerを URI フラグメント識別子として使用する方法は、RFC 6901 RFC 6901 で説明されています。2 つのフラグメント識別子構文をサポートする「application/schema+json」では、JSON Pointer 構文に一致するフラグメント識別子(空文字列を含む)は、JSON Pointerフラグメント識別子として解釈されなければなりません。
W3Cのフラグメント識別子に関するベストプラクティスW3C.WD-fragid-best-practices-20121025に従い、「application/schema+json」内のプレーンネームフラグメント識別子は、ローカルに名前が付けられたスキーマを参照するために予約されています。JSON Pointer構文に一致しないすべてのフラグメント識別子は、プレーンネームフラグメント識別子として解釈されなければなりません(MUST)。
「application/schema+json」ドキュメント内でのプレーンネームフラグメント識別子の定義と参照は、「$anchor」キーワード(セクション8.2.2)のセクションで規定されています。
6. 一般的な考慮事項 General Considerations
6.1. JSON値の範囲 Range of JSON Values
インスタンスは、JSON RFC 8259で定義されている有効なJSON値であれば何でも構いません。JSON Schemaは型に制限を設けていません。JSON Schemaは、例えばnullを含む、あらゆるJSON値を記述できます。
6.2. プログラミング言語非依存 Programming Language Independence
JSON Schemaはプログラミング言語に依存せず、データモデルで記述されるすべての値の範囲をサポートします。ただし、一部の言語やJSONパーサーでは、JSONで記述可能な値の範囲全体をメモリ上で表現できない可能性があることに注意してください。
6.3. 数学的整数 Mathematical Integers
一部のプログラミング言語やパーサーでは、浮動小数点数と整数で内部表現が異なります。
一貫性を保つため、JSONの整数値は小数部を含むエンコードは避けるべきです。
6.4. 正規表現 Regular Expressions
キーワードは、制約を表現するために正規表現を使用してもよいし、インスタンス値を正規表現に制限してもよいです。これらの正規表現は、ECMA-262 (11th edition)のセクション21.2.1 ecma262 で説明されている正規表現方言に従って有効であるべきです。
正規表現は、Unicodeをサポートするために「u」フラグ(または同等のフラグ)を使用して構築するか、ECMA-262で定義されているUnicodeサポートを提供する方法で処理する必要があります。
さらに、正規表現構造のサポートには大きなばらつきがあるため、スキーマ作成者は以下の正規表現トークンに限定する必要があります。
JSON仕様 RFC 8259 で定義されている個々のUnicode文字。
単純文字クラス ([abc])、範囲文字クラス ([a-z])。
補文字クラス ([^abc]、[^a-z])。
単純量指定子:「+」(1個以上)、「*」(0個以上)、「?」(0個または1個)、およびそれらの遅延バージョン(「+?」、「*?」、「??」)。
範囲量指定子:「{x}」(正確にx回出現)、「{x,y}」(少なくともx回、最大y回出現)、{x,}(x回以上出現)、およびそれらの遅延バージョン。
入力開始アンカー(「^」)および入力終了アンカー(「$」)。
単純グループ化("(...)")と選択("|")。
最後に、実装では正規表現を先頭でも末尾でもアンカーとして扱ってはなりません(MUST NOT)。つまり、例えばパターン "es" は "expression" に一致します。
6.5. JSON Schemaの拡張 Extending JSON Schema
追加のスキーマキーワードおよびスキーマ語彙は、どのエンティティでも定義できます。明示的な合意がない限り、スキーマ作成者は、これらの追加キーワードおよび語彙が、明示的にサポートを文書化していない実装によってサポートされることを期待してはなりません。実装は、サポートしていないキーワードをアノテーションとして扱うべきであり、キーワードの値はアノテーションの値となります。
実装は、直接サポートしていない語彙に対してハンドラを登録またはロードする機能を提供できます。このようなハンドラの登録および実装の具体的なメカニズムは、実装に依存します。
7. キーワードの動作 Keyword Behaviors
JSON Schemaキーワードは、いくつかの一般的な動作カテゴリに分類されます。アサーション(assertions)は、インスタンスが制約を満たしていることを検証し、ブール値(boolean)を返します。アノテーション(annotations)は、アプリケーションが自由に利用できる情報を付加します。アプリケーター(applicators)は、インスタンスの一部にサブスキーマを適用し、その結果を組み合わせます。
拡張キーワードは、特にアノテーションが非常に柔軟であることを念頭に置き、これらのカテゴリ内に留まるべきです。複雑な動作は、スキーマキーワードとして直接実装するよりも、アノテーションデータに基づいてアプリケーションに委任する方が通常は適切です。ただし、拡張キーワードは、特殊な目的のために他の動作を定義することもできます。
インスタンスをスキーマに対して評価するには、スキーマ内のすべてのキーワードをインスタンス内の適切な場所に対して処理する必要があります。通常、アプリケーターキーワードは、アプりケータ(したがってサブスキーマ)を持たないスキーマオブジェクトに到達するまで処理されます。インスタンス内の適切な場所が、スキーマオブジェクト内のアサーションキーワードとアノテーションキーワードに対して評価され、その結果はアプリケータのルールに従って親スキーマに収集されます。
親スキーマオブジェクトの評価は、すべてのサブスキーマが評価されると完了しますが、状況によってはアサーションの結果によって評価が途中で中断される場合があります。アノテーションを収集している場合、アサーション結果をさらに変更できないサブスキーマも含め、すべてのサブスキーマをアノテーション収集のために検査する必要があるため、アサーション結果の途中で中断することはできません。
7.1. 語彙スコープと動的スコープ Lexical Scope and Dynamic Scope
ほとんどのJSON Schemaキーワードは単独で評価できますが、同じスキーマオブジェクト内の隣接するキーワードの値や結果を考慮する必要がある場合もあります。しかし、一部のキーワードはより複雑な動作をします。
キーワードの語彙スコープは、オブジェクトと配列のネストされたJSONデータ構造によって決定されます。最大のスコープはスキーマドキュメント全体です。最小のスコープは、サブスキーマを持たない単一のスキーマオブジェクトです。
キーワードは、URI参照などの部分的な値で定義できます。この場合、JSONドキュメントの語彙構造を通して見つかる別のURI参照や完全なURIなどの値に対して解決する必要があります。「$id」、「$ref」、「$dynamicRef」といったコアキーワード、およびJSONハイパースキーマの「base」キーワードは、このような動作の例です。
「$schema」などの一部のキーワードは、スキーマリソース全体のレキシカル(lexical)スコープに適用されるため、スキーマリソースのルートスキーマにのみ出現する必要があります。
その他のキーワードは、スキーマの評価中に存在する動的スコープ(通常はインスタンスドキュメントと共に)を考慮に入れる場合があります。最も外側の動的スコープは、スキーマリソースのルートではない場合でも、処理が開始されるスキーマオブジェクトです。このルートスキーマから特定のキーワード(解決された「$ref」および「$dynamicRef」キーワードを含む)へのパスは、そのキーワードの「検証パス」とみなされます。
レキシカルスコープと動的スコープは、参照キーワードに遭遇するまで一致します。参照キーワードをたどると、処理は1つのレキシカルスコープから別のレキシカルスコープへと移行しますが、動的スコープの観点からは、参照をたどることは、値として存在するサブスキーマに降りていくことと変わりません。動的スコープを通して情報を解決する参照の反対側のキーワードは、ローカルのレキシカルスコープ上の親を調べるのではなく、参照の元の側を動的親とみなします。
動的スコープの概念は主に「$dynamicRef」と「$dynamicAnchor」で使用され、高度な機能であるため、追加のキーワードを定義する際には慎重に使用する必要があります。また、エラーや収集されたアノテーションを報告する際にも使用されます。これは、異なる動的スコープで同じ語彙スコープを繰り返し参照する可能性があるためです。このような場合、エラーまたはアノテーションを生成した動的パスをユーザーに通知することが重要です。
7.2. キーワードの相互作用 Keyword Interactions
キーワードの動作は、サブスキーマ(4.3.5項)​​および/または隣接するキーワード(同じスキーマオブジェクト内のキーワード)とそのサブスキーマのアノテーション結果に基づいて定義できます。このようなキーワードは、循環依存を引き起こしてはなりません。キーワードは、同じスキーマオブジェクト内の他のキーワードの存在または不在に基づいて動作を変更することができます(4.3項)。
7.3.デフォルトの動作 Default Behaviors
キーワードが欠落している場合、誤ったアサーション結果を生成してはならず、アノテーション結果を生成してはならず、また、他のスキーマが自身の動作定義の一部として評価される原因となってはなりません。ただし、キーワードが欠落していてもアノテーションは生成されないため、アノテーション結果がないことが他のキーワードの動作を間接的に変化させる可能性があります。
場合によっては、キーワードの欠落時のアサーション動作が特定の値によって生成される動作と同一になることがあります。キーワード定義では、そのような値が分かっている場合は、その値を明記する必要があります。ただし、デフォルトの動作を生成する値が存在すればアノテーション結果を生成する場合でも、デフォルトの動作ではアノテーションが生成されてはなりません。
アノテーションの収集は計算とメモリの両面で大きなコスト増につながる可能性があるため、実装によってはこの機能を無効にすることができます。収集されたアノテーションに関して指定されているキーワードは、適切な場合には、合理的な代替アプローチを記述する必要があります。このアプローチは、本書の「items」および「additionalProperties」キーワードによって示されています。
キーワードに対してそのような代替手段が不可能な場合、アノテーションコレクションをサポートしない実装では、それらのキーワードや、それらを含む語彙をサポートできないことに注意してください。
7.4. 識別子 Identifiers
識別子は、スキーマのURIを定義するか、参照におけるURIの解決方法に影響を与えるか(8.2.3項参照)、あるいはその両方を行います。このドキュメントで定義されているコア語彙には、いくつかの識別キーワードが定義されており、中でも「$id」が最も重要です。
正規スキーマURIは、インスタンスの処理中に変更されてはなりませんが、URI参照の解決に影響を与えるキーワードは、実行時にのみ動作が完全に決定される場合があります。
カスタム識別子キーワードは使用可能ですが、語彙設計者はコアキーワードの機能を損なわないように注意する必要があります。例えば、この仕様の「$dynamicAnchor」キーワードは、URI解決への影響を対応する「$dynamicRef」キーワードに限定し、「$ref」の動作には影響を与えません。
7.5. アプリケータ Applicators
アプリケータを使用すると、単一のスキーマオブジェクトでは実現できない、より複雑なスキーマを構築できます。インスタンスをスキーマ文書(4.3節)に対して評価する処理は、まずルートスキーマ(4.3.5節)をインスタンス文書全体に適用することから始まります。次に、適用対象スキーマを決定するために、アプリケータと呼ばれるキーワードが使用されます。これらのスキーマは、現在の場所に直接適用することも、子場所に適用することもできます。
適用対象のスキーマは、キーワードの値の全部または一部を構成するサブスキーマとして存在することができます。あるいは、アプリケータは、同じスキーマ文書内の別の場所、または別のスキーマ文書内のスキーマを参照することもできます。参照されるスキーマを識別するメカニズムは、キーワードによって定義されます。
アプリケータキーワードは、サブスキーマまたは参照スキーマのブール値アサーション(7.6節)の結果がどのように変更または結合されて、アプリケータのブール値結果が生成されるかも定義します。アプリケータは、サブスキーマのアサーション結果に対して任意のブール論理演算を適用できますが、独自の新しいアサーション条件を導入してはなりません。
アノテーション(7.7節)の結果は、インスタンスの位置とスキーマキーワードの位置とともに保存されるため、アプリケーションは複数の値をどのように解釈するかを決定できます。
7.5.1. 参照スキーマと参照元スキーマ Referenced and Referencing Schemas
7.5節で述べたように、アプリケータキーワードは、適用対象のスキーマをサブスキーマとしてアプリケータの値に含めるのではなく、直接参照することができます。このような場合、適用されるスキーマは参照スキーマ(referenced schema)と呼ばれ、アプリケータキーワードを含むスキーマは参照元スキーマ(referencing schemas)と呼ばれます。
ルートスキーマとサブスキーマは、スキーマ文書内でのスキーマの位置に基づく静的な概念ですが、参照スキーマと参照元スキーマは動的です。インスタンスをスキーマに対して評価する際に、異なるスキーマのペアが様々な参照・参照関係になる可能性があります。
「$ref」(8.2.3.1項)などの参照による適用器の中には、スキーマ文書の字句スコープを静的に解析することで参照されるスキーマを特定できるものがあります。一方、「$dynamicRef」(「$dynamicAnchor」付き)などの適用器は動的スコープを使用するため、インスタンスを使用してスキーマを評価する過程でのみ解決可能です。
7.6. アサーション Assertions
JSON Schema を使用すると、JSON ドキュメントに制約をアサートできます。アサーションは、合格または不合格のいずれかになります。このアプローチは、制約への準拠を検証したり、制約を満たすために必要な内容を文書化したりするために使用できます。
JSON Schema の実装では、インスタンスをスキーマのアサーションに対して評価すると、単一のブール値を返します。
インスタンスは、スキーマに存在するアサーションに対してのみ不合格となります。
7.6.1. アサーションとインスタンスのプリミティブ型 Assertions and Instance Primitive Types
ほとんどのアサーションは、特定のプリミティブ型内の値のみを制約します。インスタンスの型がキーワードで指定された型でない場合、インスタンスはアサーションに準拠しているとみなされます。
例えば、関連する検証語彙 json-schema-validation の「maxLength」キーワードは、特定の文字列(長すぎる文字列)のみを無効にします。インスタンスがnumber、boolean、null、array、またはobjectである場合、このアサーションに対して有効となります。
この動作により、複数のプリミティブ型を持つインスタンスでキーワードをより簡単に使用できるようになります。関連する検証語彙には、インスタンスを1つまたは複数のプリミティブ型に個別に制限できる「type」キーワードも含まれています。これにより、特定の長さの文字列またはnull値を返す関数など、使用例を簡潔に表現できます。
code:例.json
{
"type": "string", "null",
"maxLength": 255
}
もし「maxLength」によってインスタンスの型が文字列に制限される場合、この例はnull値を許容しないため、表現がかなり複雑になります。各キーワードは、明示的に指定しない限り個別に評価されるため、「maxLength」によってインスタンスが文字列に制限される場合、「type」に「null」を含めても意味がありません。
7.7. アノテーション Annotations
JSON Schemaは、インスタンスがアノテーションを含むスキーマオブジェクトとそのすべての親スキーマオブジェクトに対して検証される際に、インスタンスに情報をアノテーションとして付加できます。情報は単純な値でも、インスタンスの内容に基づいて計算された値でも構いません。
アノテーションはインスタンス内の特定の場所に付加されます。複数のサブスキーマを単一の場所に適用できるため、アプリケーションは、異なるスキーマオブジェクト内で同じスキーマキーワードによって同じインスタンスの場所に付加された異なるアノテーション値をどのように処理するかを決定する必要があります。
アサーション結果とは異なり、アノテーションデータは多様な形式をとることができ、アプリケーションは必要に応じてこれらの形式を利用できます。JSON Schemaの実装は、アプリケーションに代わって収集された情報を使用することは想定されていません。
特に指定がない限り、アノテーションキーワードの値はキーワードの値です。ただし、他の動作も可能です。例えば、JSON Hyper-Schemaのjson-hyper-schemaの「links」キーワードは、インスタンスデータに基づいて値を生成する複雑なアノテーションです。
アサーションの評価は「短絡評価」が可能ですが、アノテーションの収集には、インスタンスの場所に適用されるすべてのスキーマを検証する必要があります。たとえそれらがアサーション全体の結果に影響を与えない場合でも同様です。ただし、検証に失敗したスキーマオブジェクトのサブスキーマは、アノテーションが保持されないため、スキップされる場合があります。
7.7.1. アノテーションの収集 Collecting Annotations
アノテーションは、アノテーション収集動作を明示的に定義するキーワードによって収集されます。ブール型スキーマはキーワードを使用しないため、アノテーションを生成できないことに注意してください。
収集されたアノテーションには、以下の情報が含まれている必要があります。
アノテーションを生成するキーワードの名前
アノテーションが添付されているインスタンスの場所(JSONポインタ)
スキーマの場所のパス(「$ref」などの参照キーワードをたどって絶対スキーマの場所に到達する方法を示す)
アノテーションを添付するキーワードの絶対スキーマの場所(URI)。上記のスキーマの場所のパスと同じ場合は省略できます。
添付された値
7.7.1.1. 複数の値の区別
アプリケーションは、値を提供したスキーマの場所に基づいて、複数のアノテーション値のうちどれを使用するかを決定できます。これは、柔軟な使用を可能にするためのものです。スキーマの場所を収集することで、このような使用が容易になります。
例えば、検証仕様json-schema-validationのアノテーションとアサーションを使用する以下のスキーマを考えてみましょう。
なお、一部の行は分かりやすくするために折り返されています。
code:例.json
{
"title": "Feature list",
"type": "array",
"prefixItems": [
{
"title": "Feature A",
"properties": {
"enabled": {
"$ref": "#/$defs/enabledToggle",
"default": true
}
}
},
{
"title": "Feature B",
"properties": {
"enabled": {
"description": "If set to null, Feature B
inherits the enabled
value from Feature A",
"$ref": "#/$defs/enabledToggle"
}
}
}
],
"$defs": {
"enabledToggle": {
"title": "Enabled",
"description": "Whether the feature is enabled (true),
disabled (false), or under
automatic control (null)",
"type": "boolean", "null",
"default": null
}
}
}
この例では、機能Aと機能Bの両方で、再利用可能な「enabledToggle」スキーマが使用されています。このスキーマは、「title」、「description」、「default」というアノテーションを使用します。そのため、アプリケーションは、機能Aの追加の「default」値と機能Bの追加の「description」値をどのように処理するかを決定する必要があります。
アプリケーションプログラマとスキーマ作成者は、使用方法について合意する必要があります。この例では、最も具体的な「default」値を使用し、それ以外のより一般的な「default」値は無視することに合意したと仮定します。また、すべての「description」テキストを、最も一般的なものから最も具体的なものへと順に使用することに合意したと仮定します。これは、スキーマ作成者が、このように組み合わせても正しく機能する説明文を作成する必要があることを意味します。
アプリケーションは、スキーマの場所パスを使用して、どの値がどの値に対応しているかを判断できます。機能の直近の「enabled」プロパティスキーマの値はより具体的ですが、「$ref」で参照される再利用可能なスキーマの値はより汎用的です。スキーマの場所パスは、各値が「$ref」を介して見つかったかどうかを示します。
したがって、機能Aはデフォルト値としてtrueを使用し、機能Bは汎用的なデフォルト値としてnullを使用します。機能Aは「enabledToggle」スキーマの汎用的な説明のみを持ちますが、機能Bはその説明に加えて、null値の解釈方法を説明するローカルで定義された説明を追加します。
なお、別のアプリケーションでは、他にも妥当なアプローチが考えられます。例えば、アプリケーションによっては、スキーマの場所に関係なく、「default」に2つの異なる値が存在することをエラーとみなす場合があります。
7.7.1.2. アノテーションとアサーション
偽のアサーション結果を生成するスキーマオブジェクトは、自身のキーワードまたはサブスキーマのキーワードから、いかなるアノテーション結果も生成してはなりません。
全体的なスキーマ結果には、他のスキーマの場所から収集された注釈が含まれる場合があることに注意してください。このスキーマを例にとると、次のようになります。
code:例.json
{
"oneOf": [
{
"title": "Integer Value",
"type": "integer"
},
{
"title": "String Value",
"type": "string"
}
]
}
インスタンス「This is a string」に対して、タイトル注釈「Integer Value」は、そのスキーマオブジェクトの型アサーションが失敗するため破棄されます。一方、タイトル注釈「String Value」は、インスタンスが文字列型のアサーションに合格するため保持されます。
7.7.1.3. 注釈とアプライケータ
アプライケータキーワードは、独自の注釈結果を定義する可能性に加えて、サブスキーマまたは参照スキーマで収集された注釈を集約します。
7.8. 予約済みロケーション
4つ目のカテゴリのキーワードは、再利用可能なコンポーネント、またはスキーマ作成者にとって重要だが再利用には適さないデータを格納するためのロケーションを予約するものです。これらのキーワードは、検証結果や注釈結果には影響しません。コア語彙におけるこれらのキーワードの目的は、特定の目的のためにロケーションが利用可能であり、拡張キーワードによって再定義されないようにすることです。
これらのキーワードは結果に直接影響しませんが、9.4.2項で説明したように、再利用可能なスキーマのためにロケーションを予約する認識されない拡張キーワードは、特定の状況下で参照との間で望ましくない相互作用を引き起こす可能性があります。
7.9. インスタンスデータの読み込み
本書および関連文書で定義されている語彙には、インスタンスデータを対象としたり、インスタンスデータを読み込むためのキーワードは定義されていませんが、他の語彙ではそのような機能を持たせることが可能です。
キーワードは、JSONポインタまたは相対JSONポインタを使用して、現在の評価場所以外のインスタンスの一部を調べるように定義できます。
相対JSONポインタを使用して場所を調整できるキーワードは、デフォルト値が必要な場合、現在の場所を使用するように設定すべきです。
8. JSON Schema コア語彙
このセクションで宣言されているキーワード(すべて「$」で始まる)は、JSONスキーマコア語彙を構成します。これらのキーワードは、複数のドキュメントにまたがるものを含め、あらゆるスキーマまたはメタスキーマを処理するために必須であるか、あるいは相互運用性を保証する必要がある目的のために予約されているキーワードです。
コア語彙は、後続の語彙の処理をブートストラップするために、常に必須とみなされなければなりません。「$vocabulary」(セクション8.1)キーワードを使用して使用する語彙を宣言するメタスキーマは、コア語彙を明示的にリストする必要があり、その値は必須であることを示す「true」でなければなりません。
この語彙(およびこの語彙のみ)に「false」の値が指定された場合の動作は未定義です。また、「$vocabulary」が存在するにもかかわらずコア語彙が含まれていない場合の動作も未定義です。ただし、実装においてはこれらのケースを検出し、発生した場合にはエラーを発生させることを推奨します。メタスキーマがオプションでCoreを使用するという宣言は意味を持ちません。
「$vocabulary」を使用しないメタスキーマは、Core語彙のURIがtrueの値で指定されている場合と同様に、Core語彙を必要とするものとみなさなければなりません。
Core語彙の現在のURIは、<https://json-schema.org/draft/2020-12/vocab/core>です。
対応するメタスキーマの現在のURIは、https://json-schema.org/draft/2020-12/meta/coreです。
「$」プレフィックスはCore語彙のために正式に予約されているわけではありませんが、将来的な衝突を避けるため、拡張キーワード(語彙内またはその他の場合)は「$」以外の文字で始めることを推奨します。
8.1.メタスキーマと語彙
実装がスキーマをどのように解釈するかを規定するために、メタスキーマと語彙という2つの概念が用いられます。すべてのスキーマにはメタスキーマがあり、これは「$schema」キーワードを使用して宣言できます。
メタスキーマには2つの目的があります。
使用する語彙の宣言
メタスキーマに「$vocabulary」キーワードが出現すると、そのメタスキーマを参照するスキーマで使用可能な語彙が宣言されます。語彙はキーワードの意味と一般的な構文を定義します。
有効なスキーマ構文の記述
スキーマは、使用可能なキーワードの構文を制約するメタスキーマに対して、必ず検証に合格する必要があります。記述された構文は、宣言された語彙と互換性があることが求められます。互換性のない構文を記述することも可能ですが、そのようなメタスキーマは有用ではないでしょう。
メタスキーマは語彙とは別個のものであり、語彙を様々な方法で組み合わせることを可能にし、メタスキーマ作成者が特定のキーワードの使用を禁止したり、開発・テストサイクル中に実施されるような厳格な構文検証を行ったりするなど、追加の制約を課すことができます。各語彙は通常、その語彙のキーワードのみで構成されるメタスキーマを識別します。
メタスキーマの作成はJSON Schemaの高度な利用方法であるため、メタスキーマ機能の設計においては、シンプルさよりも柔軟性が重視されます。
8.1.1. "$schema" キーワード
"$schema" キーワードは、JSON スキーマの方言識別子として、また、その方言用に記述された有効なスキーマのセットを記述する JSON スキーマであるリソースの識別子として使用されます。
このキーワードの値は、スキームを含む URI RFC 3986 でなければならず、この URI は正規化されていなければなりません。現在のスキーマは、この URI によって識別されるメタスキーマに対して有効でなければなりません。
この URI が取得可能なリソースを識別する場合、そのリソースのメディアタイプは "application/schema+json" であるべきです。
"$schema" キーワードは、ドキュメントのルートスキーマオブジェクトで使用されるべきであり、埋め込みスキーマリソースのルートスキーマオブジェクトで使用される場合があります。リソース以外のルートスキーマオブジェクトには使用してはなりません。ドキュメントのルートスキーマに存在しない場合、その結果としての動作は実装依存となります。
このプロパティの値は、本書および他のドキュメント、ならびに他の関係者によって定義されています。
8.1.2. キーワード「$vocabulary」
キーワード「$vocabulary」は、メタスキーマにおいて、そのメタスキーマで記述されるスキーマで使用可能な語彙を識別するために使用されます。また、各語彙が必須かオプションかを示すためにも使用されます。必須語彙は、実装がスキーマを正常に処理するために理解する必要がある語彙です。これらの情報は、方言を構成します。実装が理解する語彙は、その語彙に含まれる意味定義と整合した方法で処理されなければなりません。
このキーワードの値はオブジェクトでなければなりません。オブジェクトのプロパティ名はURI(スキーマを含む)でなければならず、このURIは正規化されていなければなりません。プロパティ名として現れる各URIは、特定のキーワードセットとその意味を識別します。
URIはURLでも構いませんが、取得可能なリソースの性質は現時点では未定義であり、将来の使用のために予約されています。語彙作成者は、語彙仕様書のURLを、text/htmlやtext/plainなどの人間が読みやすいメディア形式で、語彙URIとして使用することができます。語彙ドキュメントは、今後のドラフトで追加される可能性があります。現時点では、キーワードセットの識別とメタスキーマの検証によって、現在の「語彙」は十分に機能しているため、キーワードセットの識別で十分とみなされます。将来の語彙ドキュメント形式はJSONドキュメントとして指定されるため、それまでの間text/htmlなどのJSON以外の形式を使用しても、将来的に曖昧さが生じることはありません。
オブジェクトプロパティの値はブール値でなければなりません。値がtrueの場合、この語彙を認識しない実装は、「$schema」でこのメタスキーマを宣言するスキーマの処理を拒否しなければなりません。値がfalseの場合、この語彙を認識しない実装は、そのようなスキーマの処理を続行すべきです。実装が語彙を理解している場合は、この値は影響を与えません。
6.5項に従い、認識されないキーワードは注釈として扱うべきです。これは、認識されない語彙で定義されたキーワードについても同様です。現在、語彙で定義されている認識されないキーワードと、どの語彙にも含まれていない認識されないキーワードを区別することはできません。
メタスキーマとして使用することを意図したスキーマ文書のルートスキーマでは、「$vocabulary」キーワードを使用する必要があります。サブスキーマには使用してはなりません。
メタスキーマとして処理されないスキーマ文書では、「$vocabulary」キーワードは無視する必要があります。これにより、検証者がメタスキーマMで宣言された語彙を理解する必要なく、メタスキーマMを自身のメタスキーマM'に対して検証することが可能になります。
8.1.2.1.デフォルト語彙
「$vocabulary」が存在しない場合、実装は、参照スキーマの「$schema」キーワードのURI値からメタスキーマが認識されれば、メタスキーマに基づいて動作を決定してもよい。これは、語彙が存在する以前に、動作(ハイパースキーマの使用など)が認識されていた方法である。
スキーマによって参照されるメタスキーマが認識されない、または存在しない場合、動作は実装定義となる。実装がスキーマの処理を進める場合、コア語彙の使用を前提としなければならない。実装が特定の目的のために構築されている場合、その目的に最も関連性の高いすべての語彙の使用を前提とすべきである。
例えば、バリデーターである実装は、この仕様および関連する検証仕様に含まれるすべての語彙の使用を前提とすべきである。
8.1.2.2. 語彙の非継承性
「$vocabulary」の処理制限により、「$ref」または類似のキーワードを使用して他のメタスキーマを参照するメタスキーマは、それらのメタスキーマの語彙宣言を自動的に継承しないことに注意してください。メタスキーマとして使用することを意図した各スキーマ文書のルートには、これらの宣言をすべて繰り返す必要があります。これは、サンプルメタスキーマ(付録D.2)で示されています。この要件により、実装者は各メタスキーマのすべての語彙要件情報を一箇所で見つけることができます。スキーマの拡張性により、よりきめ細かいメタスキーマを参照によって組み合わせる方法は無数に存在するため、実装者がすべての可能性を想定して参照先のメタスキーマ内の語彙を検索することを要求すると、過度の負担となります。
8.1.3.メタスキーマおよび語彙URIの更新
エラーを修正するために、更新された語彙およびメタスキーマURIは、仕様ドラフト間で公開される場合があります。実装においては、この仕様ドラフト以降、次の仕様ドラフト以前の日付のURIは、ここに記載されているURIと同じ構文と意味を示すものとして扱うべきです。
8.2. ベースURI、アンカー、および逆参照
広大なエコシステムにおけるスキーマを区別するために、スキーマはURI RFC 3986 によって識別され、URIを指定することで他のスキーマへの参照を埋め込むことができます。
いくつかのキーワードは、相対URI参照 RFC 3986 または相対URI参照を構築するために使用される値を受け入れることができます。これらのキーワードの場合、参照を解決するためにベースURIを設定する必要があります。
8.2.1. "$id" キーワード
"$id" キーワードは、スキーマリソースをその正規URI RFC 6596 で識別します。
このURIは識別子であり、必ずしもネットワークロケータではないことに注意してください。ネットワークアドレス指定可能なURLの場合、スキーマは正規URIからダウンロードできる必要はありません。
このキーワードが存在する場合、その値は文字列でなければならず、有効なURI参照RFC 3986を表す必要があります。このURI参照は正規化されるべきであり、絶対URIRFC 3986(フラグメントなし)または空のフラグメントを持つURIに解決されなければなりません。
空のフラグメント形式は推奨されず、後方互換性のためにのみ保持されています。これは、application/schema+jsonメディアタイプが、空のフラグメントを持つURIは、フラグメントを削除した同じURIと同じリソースを識別すると定義しているためです。しかし、この等価性はRFC3986の正規化プロセスRFC 3986の一部ではないため、実装者およびスキーマ作成者は、汎用URIライブラリがこれを理解できると想定することはできません。
したがって、「$id」には空でないフラグメントを含めてはならず、空のフラグメントを含めるべきでもありません。絶対URI形式は、空のフラグメントの有無にかかわらず、正規URIとみなされなければなりません。現在、空のフラグメントが許可されているのは、古いメタスキーマの「$id」(または以前は「id」)に空のフラグメントが含まれているためです。将来のドラフトでは、「$id」における空のフラグメントさえも完全に禁止される可能性があります。
絶対URIは、RFC 3986セクション5.1.1 RFC 3986(コンテンツに埋め込まれたベースURIに関する規定)に従い、スキーマリソース内のキーワードにおける相対URI参照のベースURIとしても機能します。
サブスキーマに「$id」が存在することは、そのサブスキーマが単一のスキーマドキュメント内の独立したスキーマリソースであることを示します。さらに、RFC 3986のセクション5.1.2 RFC 3986(エンティティのカプセル化に関する規定)に従い、サブスキーマ内の「$id」が相対URI参照である場合、その参照を解決するためのベースURIは、親スキーマリソースのURIとなります。
親スキーマオブジェクトが明示的に「$id」を持つリソースとして自身を識別していない場合、ベースURIは、前のセクションで説明した手順で確立されたドキュメント全体のURIとなります。(セクション9.1.1)
8.2.1.1. ルートスキーマの識別
JSONスキーマ文書のルートスキーマには、絶対URI RFC 3986 を持つ「$id」キーワード(スキーマは含まれるがフラグメントは含まれない)が含まれている必要があります。
8.2.2. 位置に依存しない識別子の定義
JSONポインタフラグメントを使用するには、スキーマの構造に関する知識が必要です。再利用可能なスキーマを提供することを目的にスキーマ文書を作成する場合、特定の構造上の場所に縛られないプレーンネームフラグメントを使用する方が望ましい場合があります。これにより、JSONポインタ参照を更新することなく、サブスキーマを移動できます。
このようなフラグメントを指定するには、「$anchor」および「$dynamicAnchor」キーワードを使用します。これらは識別子キーワードであり、「$id」で示されるような絶対URIではなく、プレーンネームフラグメントを作成するためにのみ使用できます。
結果として得られるフラグメントが付加されるベースURIは、該当する「$anchor」または「$dynamicAnchor」を含むスキーマリソースの正規URIです。前のセクションで説明したように、これは同一または親スキーマオブジェクト内の最も近い「$id」、あるいはRFC 3986に従って決定されるドキュメントのベースURIのいずれかです。
URIの通常の用法とは異なり、「$dynamicAnchor」は、「$dynamicRef」キーワードとともに使用される場合、フラグメントが拡張ポイントであることを示します。この低レベルの高度な機能により、メタスキーマなどの再帰スキーマを、その拡張に特定のセマンティクスを課すことなく、容易に拡張できます。詳細は「$dynamicRef」のセクション(8.2.3.2)を参照してください。
ほとんどの場合、通常のフラグメントの動作で十分であり、より直感的です。したがって、「$dynamicAnchor」を使用する明確な必要性がない限り、プレーンな名前フラグメントを作成するには「$anchor」を使用することを推奨します。
このキーワードの値は、指定されている場合は文字列でなければならず、文字(A~Z、a~z)またはアンダースコア(_)で始まり、その後に任意の数の文字、数字(0~9)、ハイフン(-)、アンダースコア(_)、ピリオド(.)が続く必要があります。これは、XMLのNCName生成におけるUS-ASCII部分xml-namesと一致します。アンカー文字列はURI参照ではないため、「#」文字は含まれません。「$anchor」:「foo」は、URIで使用されるとフラグメント「#foo」になります。詳細な例については、以下を参照してください。
同じリソース内で、「$anchor」および/または「$dynamicAnchor」を任意の組み合わせで使用して同じフラグメント名を複数回指定した場合、その効果は未定義です。実装によっては、このような使用法が検出された場合、エラーを発生させる場合があります。
8.2.3. スキーマ参照
現在のインスタンスの場所に適用するスキーマを参照するために、いくつかのキーワードを使用できます。「$ref」と「$dynamicRef」は、参照されたスキーマをインスタンスに適用する適用キーワードです。
「$ref」と「$dynamicRef」の値はURI参照であるため、スキーマを外部化したり、複数のファイルに分割したりすることが可能になり、自己参照によって再帰構造を検証する機能も提供されます。
これらのキーワードによって生成される解決済みURIは、必ずしもネットワークロケータではなく、単なる識別子です。ネットワークアドレス指定可能なURLであっても、スキーマは必ずしもそのアドレスからダウンロードできる必要はありません。また、実装は、ネットワークアドレス指定可能なURIに遭遇した際に、ネットワーク操作を実行する必要があると想定すべきではありません。
8.2.3.1. "$ref" による直接参照
"$ref" キーワードは、静的に識別されたスキーマを参照するために使用されるアプライケータです。その結果は、参照先のスキーマの結果となります。結果の決定方法がこのように定義されているため、同じスキーマオブジェクト内で他のキーワードが "$ref" と並んで使用される可能性があることに注意してください。
"$ref" キーワードの値は、URI 参照である文字列でなければなりません。現在の URI ベースに対して解決され、適用するスキーマの URI が生成されます。インスタンスの評価プロセスによって参照の解決方法が変更されることはないため、この解決はスキーマのロード時に安全に実行できます。
8.2.3.2. "$dynamicRef" による動的参照
"$dynamicRef" キーワードは、完全な解決をランタイムまで遅延させるアプライケータです。インスタンスの評価中に $dynamicRef キーワードが見つかるたびに、ランタイム時に解決されます。
$dynamicAnchor と $dynamicRef は、主に再帰スキーマ(自身を参照するスキーマ)で役立つ協調拡張メカニズムを実装します。拡張ポイントと実行時に決定される拡張ターゲットはどちらも $dynamicAnchor で定義され、$dynamicRef で参照された場合にのみ実行時動的な動作を示します。
$dynamicRef プロパティの値は、URI 参照である文字列でなければなりません。現在の URI ベースに対して解決され、実行時解決の開始点として使用される URI が生成されます。この初期解決は、スキーマのロード時に安全に実行できます。
初期解決された開始点 URI に $dynamicAnchor キーワードによって作成されたフラグメントが含まれている場合、初期 URI は、動的スコープ (7.1 項) 内の最も外側のスキーマ リソースの URI (フラグメントを含む) に置き換えられなければなりません。このスキーマ リソースは、$dynamicAnchor で同じ名前のフラグメントを定義しています。
それ以外の場合、動作は $ref と同一であり、実行時解決は不要です。
これらのキーワードを使用した完全な例については、付録Cを参照してください。2019年以前のドラフトにおけるハイパースキーマ・メタスキーマと、このドラフトにおけるハイパースキーマ・メタスキーマの違いは、これらのキーワードの有用性を劇的に示しています。
8.2.4. "$defs" を使用したスキーマの再利用
"$defs" キーワードは、スキーマ作成者が再利用可能なJSONスキーマをより汎用的なスキーマにインライン化するための場所を確保します。このキーワードは、検証結果に直接影響を与えません。
このキーワードの値はオブジェクトでなければなりません。このオブジェクトの各メンバー値は、有効なJSONスキーマでなければなりません。
例として、正の整数の配列を記述するスキーマを以下に示します。正の整数制約は、$defs のサブスキーマです。
code:例.json
{
"type": "array",
"items": { "$ref": "#/$defs/positiveInteger" },
"$defs": {
"positiveInteger": {
"type": "integer",
"exclusiveMinimum": 0
}
}
}
8.3. "$comment" を使用したコメント
このキーワードは、スキーマ作成者がスキーマの閲覧者または保守者に対してコメントを記述するための場所を確保します。
このキーワードの値は文字列でなければなりません。実装では、この文字列をエンドユーザーに表示してはなりません。スキーマ編集ツールは、このキーワードの表示と編集をサポートする必要があります。このキーワードの値は、スキーマを使用する開発者向けのデバッグ出力またはエラー出力に使用される場合があります。
スキーマ語彙は、語彙キーワードを含む任意のオブジェクト内で $comment を許可する必要があります。実装は、語彙で明示的に禁止されていない限り、「$comment」が許可されていると想定してもよい。語彙は、この仕様で説明されている範囲を超えて、「$comment」に何らかの効果を持たせてはならない。
他のメディアタイプやプログラミング言語をapplication/schema+jsonと相互に変換するツールは、そのメディアタイプやプログラミング言語のネイティブコメントを「$comment」値に変換するか、または「$comment」値から変換するかを選択してもよい。ネイティブコメントと「$comment」プロパティの両方が存在する場合の変換動作は、実装に依存する。
実装は、処理中の任意の時点で「$comment」値を削除してもよい。特に、デプロイされるスキーマのサイズが懸念される場合、これによりスキーマを短縮できる。
実装は、「$comment」プロパティの存在、非存在、または内容に基づいて、他のいかなるアクションも実行してはならない。特に、「$comment」の値をアノテーションの結果として収集してはならない。
9. スキーマの読み込みと処理
9.1. スキーマの読み込み
9.1.1. 初期ベースURI
RFC3986 セクション5.1 RFC 3986 では、ドキュメントのデフォルトベースURIを決定する方法が定義されています。
補足として、スキーマの初期ベースURIは、ネットワーク上の場所、ローカルファイルシステム、または既知のスキームのURIで識別可能なその他の状況など、スキーマが見つかった場所のURIです。
スキーマドキュメントに「$id」(コンテンツに埋め込まれている)による明示的なベースURIが定義されていない場合、ベースURIはRFC 3986 セクション5 RFC 3986 に従って決定されます。
ソースが不明な場合、またはソースのURIスキームが不明な場合は、RFC 3986 セクション5.1.4 RFC 3986 に記載されているように、適切な実装固有のデフォルトURIを使用することができます。実装においては、想定されるデフォルトのベースURIを文書化することが推奨されます。
スキーマオブジェクトが別のメディアタイプのドキュメントに埋め込まれている場合、初期ベースURIはそのメディアタイプの規則に従って決定されます。
前のセクションで説明した「$id」キーワードがルートスキーマに存在しない限り、このベースURIはスキーマドキュメントのルートスキーマリソースの正規URIとみなされるべきです。
9.1.2. 参照スキーマの読み込み
リモートスキーマを識別するためにURIを使用することは、必ずしも何かがダウンロードされることを意味するわけではありません。むしろ、JSONスキーマの実装は、使用するスキーマと、それらを識別するURIを事前に把握しておくべきです。
例えば、実行時までダウンロードするスキーマがわからない汎用ユーザーエージェントによってスキーマがダウンロードされる場合は、「ハイパーメディアでの使用法」(9.5.1節)を参照してください。
実装は、バリデーターがスキーマに対して持つ信頼度に応じて、任意のURIを任意のスキーマに関連付けたり、スキーマの「$id」で指定されたURIを自動的に関連付けたりできる必要があります。このようなURIとスキーマは、インスタンス処理前に実装に提供することも、スキーマ文書の処理中に文書内に記述することもできます。付録Aに示すように、関連付けは生成されます。
1つのスキーマは複数のURIを持つ可能性があります(そしておそらく持つでしょう)が、1つのURIで複数のスキーマを識別することはできません。複数のスキーマが同じURIを識別しようとした場合、バリデーターはエラーを発生させる必要があります。
9.1.3. メタスキーマの検出
実装は、別のスキーマの「$schema」キーワードによってメタスキーマとして識別されたスキーマを、メタスキーマとして認識する必要があります。つまり、1つのスキーマ文書が、通常のスキーマとみなされる場合と、メタスキーマとみなされる場合があります。
自身のメタスキーマであるスキーマを検証する場合、実装がそれを通常のスキーマとして処理し始めると、その規則に従って処理されます。しかし、自身の「$schema」値をチェックした結果として2度目にロードされると、メタスキーマとして扱われます。つまり、同じドキュメントが1つのセッション内で2通りの処理を受けることになります。
実装によっては、実装固有の目的(例えば、よく使用されるメタスキーマを事前にロードし、その語彙サポート要件を事前にチェックするなど)のために、スキーマをメタスキーマとして明示的に渡すことを許可する場合があります。メタスキーマの作成者は、このような機能が実装間で相互運用可能であることを期待してはなりません。
9.2. 参照解除
スキーマは、JSONポインタや「$id」で直接指定されたURIなど、指定されたURIによって識別できます。いずれの場合も、「$ref」参照の参照解除は、まずRFC 3986 RFC 3986に従って、現在のベースURIに対してその値をURI参照として解決することから始まります。
結果として得られたURIが、現在のドキュメント内、または実装に提供されている別のスキーマドキュメント内のスキーマを識別する場合、そのスキーマは自動的に使用されるべきです。
例えば、次のスキーマを考えてみましょう。
code:例.json
{
"$id": "https://example.net/root.json",
"items": {
"type": "array",
"items": { "$ref": "#item" }
},
"$defs": {
"single": {
"$anchor": "item",
"type": "object",
"additionalProperties": { "$ref": "other.json" }
}
}
}
実装が <#/$defs/single> スキーマに遭遇すると、現在のベース URI に対して $anchor 値をフラグメント名として解決し、<https://example.net/root.json#item> を生成します。
次に、実装が <#/items> スキーマ内を調べると、<#item> 参照に遭遇し、これを <https://example.net/root.json#item> に解決します。これは同じドキュメント内で定義されているため、自動的に使用できます。
実装が other.json への参照に遭遇すると、これを <https://example.net/other.json> に解決しますが、これはこのドキュメント内で定義されていません。この識別子を持つスキーマが実装に別途提供されている場合は、これも自動的に使用できます。参照先のスキーマが不明な場合、実装はどうすべきでしょうか?自動的なネットワーク逆参照が許可される状況はありますか?同一オリジンポリシーはありますか?ユーザーが設定可能なオプションはありますか? Hyper-Schemaで記述されるような進化するAPIの場合、新しいスキーマがシステムに動的に追加されることが想定されるため、スキーマ文書の事前読み込みを絶対的な要件とすることは現実的ではありません。
9.2.1. JSON Pointer フラグメントと埋め込みスキーマリソース
JSONポインタURIフラグメントはスキーマ文書の構造に基づいて構築されるため、埋め込みスキーマリソースとそのサブスキーマは、自身の正規URI、または包含するリソースのURIを基準としたJSONポインタフラグメントによって識別できます。
概念的には、リンクされたスキーマリソースのセットは、各リソースがスキーマ参照で接続された個別の文書である場合(セクション8.2.3参照)、または1つ以上のスキーマリソースがサブスキーマとして埋め込まれた単一の文書として構造化されている場合、同一の動作をするはずです。
親スキーマリソースのURIを基準としたJSONポインタフラグメントを含むURIは、埋め込みスキーマが別のドキュメントに移動されて参照されると無効になるため、アプリケーションやスキーマは、埋め込みスキーマリソースまたはその内部の場所を識別するために、このようなURIを使用すべきではありません。
以下のスキーマドキュメントには、別のスキーマリソースが埋め込まれています。
code:例.json
{
"$id": "https://example.com/foo",
"items": {
"$id": "https://example.com/bar",
"additionalProperties": { }
}
}
URI "https://example.com/foo#/items" は、埋め込みリソースである「items」スキーマを指しています。しかし、このスキーマリソースの正規URIは "https://example.com/bar" です。
この埋め込みリソース内の "additionalProperties" スキーマについては、URI "https://example.com/foo#/items/additionalProperties" は正しいオブジェクトを指していますが、そのオブジェクトのURIは、リソースの正規URIに対して "https://example.com/bar#/additionalProperties" となります。
次に、「$ref」のURI値を使用して参照リンクされた以下の2つのスキーマリソースについて考えてみましょう。
code:例.json
{
"$id": "https://example.com/foo",
"items": {
"$ref": "bar"
}
}
{
"$id": "https://example.com/bar",
"additionalProperties": { }
}
ここで、「https://example.com/bar#/additionalProperties 」は、「bar」スキーマリソースの正規URIにJSON Pointerフラグメントを追加したもので、依然として有効です。一方、「https://example.com/foo#/items/additionalProperties 」は、「foo」スキーマリソースの正規URIにJSON Pointerフラグメントを追加したもので、解決されません。
また、「https://example.com/foo#/items 」はどちらの形式でも有効ですが、解決される値は異なります。このURIは、リソースの取得URIと同様の機能を発揮します。このURIは有効ですが、2番目の(埋め込みではない)形式で「$ref」を含むオブジェクトを明示的に識別したい場合を除き、埋め込みまたは参照されているリソースの「$id」を使用する方がより堅牢です。
実装によっては、リソースの正規URI以外のベースURIと、そのベースからのJSONポインタフラグメントを組み合わせたURIによるスキーマリソースコンテンツのアドレス指定をサポートしない場合があります。そのため、スキーマ作成者はこのようなURIに依存すべきではありません。このようなURIを使用すると、相互運用性が低下する可能性があるためです。これは、スキーマリソースが再編成された場合、1つを除くすべてのURIが脆弱になるため、実装が可能なベースURIとそれぞれのJSONポインタフラグメントのスタック全体を追跡する必要がないようにするためです。このことは簡単なので禁止する意味はないと主張する人もいれば、スキーマ識別を複雑にするため禁止すべきだと主張する人もいます。このトピックに関するフィードバックをお待ちしています。議論の結果、「canonical」という用語の使用をやめ、スキーマリソースの境界を越えて参照するJSONポインタは未定義、あるいは禁止されている動作であるとして扱うべきであると判断しました(https://github.com/json-schema-org/json-schema-spec/issues/937 、https://github.com/json-schema-org/json-schema-spec/issues/1183 )。
このような非canonical URI構築のさらなる例、および代わりに使用すべき適切なcanonical URIベースのフラグメントについては、付録Aに記載されています。
9.3. 複合ドキュメント
複合スキーマドキュメントは、複数の埋め込みJSONスキーマリソースを同一ドキュメントにバンドルして転送を容易にしたJSONドキュメント(「バンドル型」スキーマと呼ばれることもあります)として定義されます。
各埋め込みスキーマリソースは、語彙サポートの判定を含む、標準的なスキーマのロードおよび処理要件に従って、個別のスキーマリソースとして扱われなければなりません。
9.3.1. バンドル
複合スキーマ文書を作成するためのバンドル処理は、外部スキーマリソースへの参照(「$ref」など)を取得し、参照先の文書内に参照先のスキーマリソースを埋め込む処理として定義されます。バンドル処理は、ベース文書および参照先/埋め込み先の文書内のすべてのURI(参照に使用されるURI)を変更する必要がないように行うべきです。
埋め込まれた各JSONスキーマリソースは、「$id」キーワードを使用してURIで自身を識別する必要があり、スキーマリソースのルートディレクトリにおいて、「$schema」キーワードを使用して使用するダイアレクトを識別するべきです。「$id」のURI識別子値は絶対URIにすることが推奨されます。
参照によるアプライケータによって参照されるスキーマリソースがバンドルされる場合、そのスキーマリソースは、包含するスキーマのルートディレクトリにある「$defs」オブジェクトの値として配置されることが推奨されます。埋め込まれたスキーマ リソースの「$defs」のキーは、バンドルされたスキーマの「$id」、またはアプリケーションが定義したその他の一意の識別子(UUIDなど)にすることができます。このキーはJSONスキーマ内で参照されることを想定していませんが、アプリケーションがバンドル処理を支援するために使用できます。
スキーマ リソースは、「$defs」以外の場所に埋め込むことができます。その場所はスキーマ値として定義されます。
バンドルされたスキーマ リソースは、参照元のスキーマ オブジェクトを置き換えたり、スキーマ リソースを他のアプリケータ キーワードでラップしたりすることによってバンドルしてはなりません。
同一の出力を生成するために、包含スキーマ ドキュメント内の、以前は外部スキーマ リソースだったものへの参照は変更してはならず、埋め込まれたスキーマ リソースの「$id」を使用するスキーマに解決される必要があります。このような同一の出力には、検証評価、および結果として得られる注釈やエラーで使用されるURIまたはパスが含まれます。
複合スキーマ文書を作成する主な方法はバンドル処理であることが多いですが、個々のスキーマリソースが事前に存在しない状態で、手動で作成される場合もあり、その場合も想定されます。
9.3.2. 異なるダイアレクトとデフォルトのダイアレクト
単一の文書内に複数のスキーマリソースが存在する場合、処理するダイアレクトが定義されていないスキーマリソースは、囲んでいるリソースと同じダイアレクトで処理されなければなりません。
参照可能なスキーマはすべて埋め込むことができるため、埋め込まれたスキーマリソースは、囲んでいるリソースの「$schema」値を使用して、異なる処理ダイアレクトを指定できます。
9.3.3. 検証
複合スキーマ文書には、異なるダイアレクトを使用していると識別される埋め込みリソースが含まれる可能性があるため、これらの文書は、複合スキーマ文書をインスタンスとしてメタスキーマを適用して検証すべきではありません。スキーマ文書を検証するために、別の検証プロセスを提供することを推奨します。各スキーマリソースは、関連付けられたメタスキーマに対して個別に検証されるべきです。検証対象のスキーマが分かっている場合は、「$id」を使用することで、そのスキーマが複合スキーマ文書であるかどうかを識別できます。「$id」は、文書のルート以外で使用される場合、埋め込みリソースを識別します。
すべての埋め込みリソースが同じ方言を使用していると識別される複合スキーマ文書、または「$schema」が省略され、したがって囲んでいるリソースの方言がデフォルトで使用される複合スキーマ文書は、適切なメタスキーマを適用することで検証できます。
9.4. 注意事項
9.4.1. 無限再帰の防止
スキーマは、インスタンスに対して無限ループで実行されてはなりません。例えば、2つのスキーマ「#alice」と「#bob」が、互いに参照し合う「allOf」プロパティを持っている場合、単純なバリデーターはインスタンスの検証中に無限再帰ループに陥る可能性があります。スキーマは、このような無限再帰的なネストを使用すべきではありません。動作は未定義です。
9.4.2. スキーマ以外のオブジェクトへの参照
サブスキーマオブジェクト(またはブール値)は、既知のアプライケーターキーワード、または「$defs」(セクション8.2.4)のように1つ以上のサブスキーマを値として受け取るロケーション予約キーワードで使用されていることで識別されます。これらのキーワードは、「$defs」やこのドキュメントに記載されている標準アプライケータ、既知の語彙からの拡張キーワード、または実装固有のカスタムキーワードである可能性があります。
未知のキーワードによる多階層構造は、ネストされたサブスキーマを導入する可能性があり、それらは「$id」の処理ルールに従うことになります。したがって、このような認識されない構造に参照ターゲットが存在する場合、確実に実装することはできず、結果として生じる動作は未定義となります。同様に、既知のキーワードの下にある参照ターゲットで、その値がスキーマではないことがわかっている場合も、実装側がそのようなターゲットを検出する必要性を負わないようにするため、動作は未定義となります。これらのシナリオは、HTTP経由でスキーマを取得しようとした際に、Content-Typeがapplication/schema+json以外のレスポンスを受け取った場合と類似しています。実装側は確かにそれをスキーマとして解釈しようと試みることはできますが、オリジンサーバーはそれが実際にスキーマであるという保証を提供していません。したがって、それをスキーマとして解釈することはセキュリティ上の問題を引き起こし、予期しない結果を招く可能性があります。
構文と意味が「$defs」と同一の単一レベルのカスタムキーワードは、間に「$id」キーワードを挿入できないため、参照ターゲットをスキーマとして使用しようとする実装においても正しく動作します。ただし、この動作は実装固有のものであり、相互運用性のために依存してはなりません。
9.5. インスタンスとスキーマの関連付け
9.5.1. ハイパーメディアでの利用
JSONは、自動化されたAPIやロボット向けにHTTPサーバーで広く採用されています。このセクションでは、メディアタイプとWebリンクRFC 8288をサポートするプロトコルと併用する場合に、JSONドキュメントの処理をよりRESTfulな方法で強化する方法について説明します。
9.5.1.1. スキーマへのリンク
スキーマによって記述されるインスタンスは、Linked Data Protocol 1.0のセクション8.1W3C.REC-ldp-20150226で定義されているリンク関係「describedby」を使用して、ダウンロード可能なJSONスキーマへのリンクを提供することが推奨されます。
HTTPでは、このようなリンクはLinkヘッダーRFC 8288を使用して任意のレスポンスに添付できます。このようなヘッダーの例は次のとおりです。
code:Link
Link: <https://example.com/my-hyper-schema>; rel="describedby"
9.5.1.2. HTTP 上での利用
ネットワーク上のハイパーメディアシステムにおいて、スキーマの配信には HTTP RFC 7231 が頻繁に用いられます。しかし、クライアントがスキーマを必要以上に頻繁にネットワーク経由で取得しようとすると、サーバー管理者にとって問題となる可能性があります。スキーマを長期間キャッシュすることが可能な場合、このような事態は避けるべきです。
HTTP サーバーは JSON スキーマに長期キャッシュヘッダーを設定する必要があります。HTTP クライアントはキャッシュヘッダーを遵守し、有効期間内にドキュメントを再要求しないようにしてください。分散システムでは、共有キャッシュおよび/またはキャッシュプロキシを利用する必要があります。
クライアントは、JSON スキーマの実装またはソフトウェア製品に固有の User-Agent ヘッダーを設定または付加する必要があります。シンボルは重要度の高い順にリストされているため、JSON スキーマライブラリ名/バージョンは、より一般的な HTTP ライブラリ名(存在する場合)の前に記述する必要があります。例:
code:User-Agent
User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0
クライアントは「From」ヘッダー付きのリクエストを送信できるようにすべきです。これにより、サーバーオペレーターは、問題のある可能性のあるスクリプトの所有者に連絡を取ることができます。
10. サブスキーマ適用用語彙
このセクションでは、他の語彙の基盤として使用することが推奨される、適用キーワードの語彙を定義します。
「$vocabulary」を使用しないメタスキーマは、そのURIがtrueの値で存在する場合と同様に、この語彙を必要とするものとみなすべきです。
適用語彙として知られるこの語彙の現在のURIは、<https://json-schema.org/draft/2020-12/vocab/applicator >です。
対応するメタスキーマの現在のURIは、https://json-schema.org/draft/2020-12/meta/applicator です。
10.1. キーワードの独立性
スキーマキーワードは通常、互いに結果に影響を与えず、独立して動作します。
スキーマ作成者の便宜のため、この語彙に含まれるキーワードにはいくつかの例外があります。
「additionalProperties」は、「properties」と「patternProperties」に基づいて動作が定義されます。
「items」は、「prefixItems」に基づいて動作が定義されます。
「contains」は、検証語彙における「minContains」の存在と値によって動作が影響を受けます。
10.2. サブスキーマをその場で適用するためのキーワード
これらのキーワードは、親スキーマが適用されるインスタンス内の同じ場所にサブスキーマを適用します。これにより、サブスキーマの結果をさまざまな方法で組み合わせたり、変更したりできます。
これらのキーワードのサブスキーマは、インスタンスを完全に独立して評価するため、あるサブスキーマの結果が兄弟サブスキーマの結果に影響を与えてはなりません。したがって、サブスキーマは任意の順序で適用できます。
10.2.1. サブスキーマを論理的に適用するためのキーワード
これらのキーワードは、サブスキーマのブール値アサーション結果を結合または変更するための論理演算子に対応します。これらはアノテーションの収集に直接的な影響はありませんが、同じアノテーションキーワードを異なる値でインスタンスの場所に適用することを可能にします。アノテーションキーワードは、このような値を組み合わせるための独自のルールを定義します。
10.2.1.1. allOf
このキーワードの値は、空でない配列でなければなりません。配列の各要素は、有効なJSONスキーマでなければなりません。
インスタンスは、このキーワードの値で定義されたすべてのスキーマに対して検証に成功した場合に、このキーワードに対して検証に成功したとみなされます。
10.2.1.2. anyOf
このキーワードの値は、空でない配列でなければなりません。配列の各要素は、有効なJSONスキーマでなければなりません。
インスタンスは、このキーワードの値で定義された少なくとも1つのスキーマに対して検証に成功した場合に、このキーワードに対して検証に成功したとみなされます。アノテーションを収集する際は、すべてのサブスキーマを検査し、検証に成功した各サブスキーマからアノテーションを収集する必要があることに注意してください。
10.2.1.3. oneOf
このキーワードの値は、空でない配列でなければなりません。配列の各要素は、有効なJSONスキーマでなければなりません。
インスタンスは、このキーワードの値で定義されたスキーマのうち、ちょうど1つに対して検証に成功した場合に、このキーワードに対して検証に成功したとみなされます。
10.2.1.4. not
このキーワードの値は、有効なJSONスキーマでなければなりません。
インスタンスは、このキーワードで定義されたスキーマに対して検証に失敗した場合に、このキーワードに対して有効とみなされます。
10.2.2. サブスキーマを条件付きで適用するためのキーワード
これらのキーワードのうち3つは連携して、別のサブスキーマの結果に基づいてサブスキーマを条件付きで適用する処理を実現します。4つ目のキーワードは、特定の条件ケースを指定するためのショートカットです。
「if」、「then」、「else」は、サブスキーマの境界を越えて相互に影響し合ってはなりません。つまり、「allOf」の一方のブランチにある「if」は、もう一方のブランチにある「then」または「else」に影響を与えてはなりません。
「if」、「then」、「else」が存在しない場合、デフォルトの動作はありません。特に、空のスキーマに対しては、これらのキーワードが存在するものとして扱われてはなりません。また、「if」が存在しない場合、「then」と「else」は完全に無視されなければなりません。
10.2.2.1. if
このキーワードの値は、有効なJSONスキーマでなければなりません。
このキーワードのサブスキーマの検証結果は、全体の検証結果に直接的な影響を与えません。むしろ、「then」または「else」キーワードのどちらが評価されるかを制御します。
このキーワードのサブスキーマに対して検証に成功したインスタンスは、「then」キーワードのサブスキーマ値が存在する場合、そのサブスキーマ値に対しても有効でなければなりません。
このキーワードのサブスキーマに対して検証に失敗したインスタンスは、「else」キーワードのサブスキーマ値が存在する場合、そのサブスキーマ値に対しても有効でなければなりません。
アノテーション(セクション7.7)が収集されている場合、キーワードが「then」または「else」のどちらも存在しない場合でも、通常の方法でこのキーワードのサブスキーマから収集されます。
10.2.2.2. then
このキーワードの値は、有効なJSONスキーマでなければなりません。
「if」が存在し、インスタンスがそのサブスキーマに対して検証に成功した場合、インスタンスがこのキーワードのサブスキーマに対しても検証に成功すれば、このキーワードに対する検証も成功します。
このキーワードは、「if」が存在しない場合、またはインスタンスがサブスキーマに対して検証に失敗した場合には効果がありません。実装は、このような場合、検証またはアノテーション収集のいずれの目的であれ、インスタンスをこのキーワードに対して評価してはなりません。
10.2.2.3. else
このキーワードの値は、有効なJSONスキーマでなければなりません。
「if」が存在し、インスタンスがサブスキーマに対して検証に失敗した場合でも、インスタンスがこのキーワードのサブスキーマに対して検証に成功すれば、このキーワードに対する検証は成功します。
このキーワードは、「if」が存在しない場合、またはインスタンスがサブスキーマに対して検証に成功した場合には効果がありません。実装は、このような場合、検証またはアノテーション収集のいずれの目的であれ、インスタンスをこのキーワードに対して評価してはなりません。
10.2.2.4. dependentSchemas
このキーワードは、インスタンスがオブジェクトであり、かつ特定のプロパティを含む場合に評価されるサブスキーマを指定します。
このキーワードの値は、オブジェクトでなければなりません。オブジェクト内の各値は、有効なJSONスキーマでなければなりません。
オブジェクトキーがインスタンス内のプロパティである場合、インスタンス全体がサブスキーマに対して検証される必要があります。このサブスキーマの使用は、プロパティの存在に依存します。
このキーワードを省略した場合、空のオブジェクトと同じ動作になります。
10.3. 子インスタンスへのサブスキーマ適用用キーワード
これらのキーワードはそれぞれ、子インスタンス(具体的にはオブジェクトプロパティと配列要素)にサブスキーマを適用し、その結果を結合するためのルールを定義します。
10.3.1. 配列へのサブスキーマ適用用キーワード
10.3.1.1. prefixItems
「prefixItems」の値は、有効なJSONスキーマの空でない配列でなければなりません。
インスタンスの各要素が、同じ位置にあるスキーマに対して検証に合格した場合、検証は成功します。このキーワードは配列の長さを制限しません。配列がこのキーワードの値よりも長い場合、このキーワードは長さが一致するプレフィックスのみを検証します。
このキーワードは、このキーワードがサブスキーマを適用した最大のインデックスを示す注釈値を生成します。「items」キーワードのように、インスタンスのすべてのインデックスにサブスキーマが適用された場合、この値はブール値のtrueになることがあります。この注釈は、「items」と「unevaluatedItems」の動作に影響します。
このキーワードを省略した場合、空の配列と同じアサーション動作になります。
10.3.1.2. items
「items」の値は、有効なJSON Schemaでなければなりません。
このキーワードは、「prefixItems」キーワードの注釈結果によって報告される、同じスキーマオブジェクト内の「prefixItems」配列の長さを超えるインデックスにあるすべてのインスタンス要素に、そのサブスキーマを適用します。そのような注釈結果が存在しない場合、「items」はすべてのインスタンス配列要素にそのサブスキーマを適用します。なお、「prefixItems」がない場合の「items」の動作は、以前のドラフトにおける「items」のスキーマ形式の動作と同一です。「prefixItems」が存在する場合、「items」の動作は、以前の「additionalItems」キーワードの動作と同一です。
インスタンス配列内のいずれかの位置に「items」サブスキーマが適用されると、ブール値「true」のアノテーション結果が生成されます。これは、残りの配列要素すべてがこのキーワードのサブスキーマに対して評価されたことを示します。このアノテーションは、未評価語彙の「unevaluatedItems」の動作に影響を与えます。
このキーワードを省略した場合、空のスキーマと同じアサーション動作になります。
実装では、同じ効果が得られる別の方法でこのキーワードを実装または最適化することもできます。例えば、「prefixItems」配列の存在とサイズを直接チェックする方法などです。アノテーション収集をサポートしていない実装は、必ずアノテーション収集をサポートする必要があります。
10.3.1.3. contains
このキーワードの値は、有効な JSON Schemaでなければなりません。
配列インスタンスは、その要素のうち少なくとも1つが指定されたスキーマに対して有効な場合、「contains」キーワードに対して有効とみなされます。ただし、「minContains」が存在し、その値が0の場合は例外で、配列インスタンスの要素がどれも指定されたスキーマに対して有効でなくても、「contains」キーワードに対して有効とみなされます。
このキーワードは、サブスキーマを適用した際にこのキーワードの検証に成功したインデックスの配列を昇順で格納したアノテーション値を生成します。サブスキーマがインスタンスのすべてのインデックスに適用された際に検証に成功した場合、この値はブール値「true」になります。このキーワードのスキーマが適用されるインスタンス配列が空の場合、このアノテーションは必ず存在する必要があります。
このアノテーションは、未評価語彙の「unevaluatedItems」の動作に影響を与え、検証語彙の「minContains」および「maxContains」キーワードの実装にも使用できます。
サブスキーマは、最初の一致が見つかった後も、他の​​キーワードで使用するための注釈を収集するために、すべての配列要素に適用する必要があります。これは、考えられるすべての注釈が収集されることを保証するためです。
10.3.2. オブジェクトにサブスキーマを適用するためのキーワード
10.3.2.1. properties
「properties」の値はオブジェクトでなければなりません。このオブジェクトの各値は、有効なJSONスキーマでなければなりません。
インスタンスとこのキーワードの値の両方に現れる名前について、その名前の子インスタンスが対応するスキーマに対して正常に検証された場合、検証は成功します。
このキーワードのアノテーション結果は、このキーワードに一致するインスタンスプロパティ名のセットです。このアノテーションは、この語彙の「additionalProperties」と、未評価語彙の「unevaluatedProperties」の動作に影響します。
このキーワードを省略した場合、空のオブジェクトと同じアサーション動作になります。
10.3.2.2. patternProperties
「patternProperties」の値はオブジェクトでなければなりません。このオブジェクトの各プロパティ名は、ECMA-262正規表現方言に準拠した有効な正規表現である必要があります。このオブジェクトの各プロパティ値は、有効なJSONスキーマである必要があります。
このキーワードの値に含まれるプロパティ名に一致する正規表現に一致するインスタンス名ごとに、その名前の子インスタンスが、一致する正規表現に対応する各スキーマに対して検証に成功した場合、検証は成功します。
このキーワードのアノテーション結果は、このキーワードに一致するインスタンスプロパティ名のセットです。このアノテーションは、「additionalProperties」(この語彙)と「unevaluatedProperties」(未評価語彙)の動作に影響します。
このキーワードを省略した場合、空のオブジェクトと同じアサーション動作になります。
10.3.2.3. additionalProperties
「additionalProperties」の値は、有効なJSONスキーマである必要があります。
このキーワードの動作は、同一スキーマオブジェクト内に「properties」と「patternProperties」が存在するかどうか、およびそれらのアノテーション結果に依存します。「additionalProperties」による検証は、「properties」または「patternProperties」のいずれのアノテーション結果にも含まれていないインスタンス名の子値にのみ適用されます。
このようなプロパティすべてについて、子インスタンスが「additionalProperties」スキーマに対して検証に合格すれば、検証は成功します。
このキーワードのアノテーション結果は、このキーワードのサブスキーマによって検証されたインスタンスプロパティ名のセットです。このアノテーションは、未評価語彙の「unevaluatedProperties」の動作に影響を与えます。
このキーワードを省略した場合、空のスキーマと同じアサーション動作になります。
実装では、同じ効果が得られる別の方法でこのキーワードを実装または最適化することもできます。例えば、「properties」内の名前と「patternProperties」内のパターンをインスタンスプロパティセットに対して直接チェックする方法などです。アノテーション収集をサポートしていない実装は、必ずアノテーション収集をサポートする必要があります。このオプションを定義するにあたり、出力形式に曖昧さが生じる可能性があるようです。この曖昧さは検証結果には影響しませんが、出力形式には影響します。曖昧さによって、注釈を使用するか、draft-07 と「同じ効果」を生み出すソリューションを使用するかによって、複数の有効な出力結果が生じる可能性があります。スキーマに不適合な注釈は削除されることが前提となります。詳細については、決定記録(https://github.com/json-schema-org/json-schema-spec/tree/HEAD/adr/2022-04-08-cref-for-ambiguity-and-fix-later-gh-spec-issue-1172.md) を参照してください。
10.3.2.4. propertyNames
「propertyNames」の値は、有効な JSON スキーマでなければなりません。
インスタンスがオブジェクトの場合、このキーワードは、インスタンス内のすべてのプロパティ名が指定されたスキーマに対して検証されるかどうかを検証します。スキーマがテストするプロパティ名は常に文字列であることに注意してください。
このキーワードを省略すると、空のスキーマと同じ動作になります。
11. 未評価箇所に関する語彙
これらのキーワードの目的は、スキーマ作成者が、隣接するキーワードの動的スコープのサブスキーマに対して正常に評価されなかった配列項目またはオブジェクトプロパティにサブスキーマを適用できるようにすることです。
これらのインスタンス項目またはプロパティは、例えば「anyOf」の分岐におけるアサーションが失敗した場合など、1つ以上の隣接するキーワードサブスキーマに対して正常に評価されなかった可能性があります。このような評価失敗は、項目またはプロパティが評価されたかどうかの判断には影響しません。評価が成功した場合のみが考慮されます。
配列内の項目またはオブジェクトプロパティが「正常に評価された」場合、それは期待されるオブジェクトまたは配列の表現に関して論理的に有効であるとみなされます。例えば、サブスキーマが車を表し、車には2~4個の車輪が必要で、「wheels」の値が6の場合、インスタンスオブジェクトは車として「評価」されず、「wheels」プロパティは「未評価(既知のものとして正常に評価された)」とみなされ、アノテーションは保持されません。
隣接するキーワードは、同じスキーマオブジェクト内のキーワードであり、動的スコープのサブスキーマには、参照ターゲットとレキシカルサブスキーマの両方が含まれることに注意してください。
これらのキーワードの動作は、検証対象のインスタンスの場所に適用される隣接キーワードのアノテーション結果に依存します。
「$vocabulary」を使用しないメタスキーマは、そのURIがtrueの値で存在する場合と同様に、この語彙を必要とするものとみなされるべきです。
この語彙(未評価アプライケータ語彙)の現在のURIは、<https://json-schema.org/draft/2020-12/vocab/unevaluated >です。
対応するメタスキーマの現在のURIは、https://json-schema.org/draft/2020-12/meta/unevaluated です。
11.1. キーワードの独立性
スキーマキーワードは通常、互いに結果に影響を与えることなく独立して動作します。ただし、この語彙のキーワードは例外です。
「unevaluatedItems」の動作は、「prefixItems」、「items」、「contains」、および自身からのアノテーションによって定義されます。
「unevaluatedProperties」の動作は、「properties」、「patternProperties」、「additionalProperties」、および自身からのアノテーションによって定義されます。
11.2. unevaluatedItems
「unevaluatedItems」の値は、有効なJSONスキーマでなければなりません。
このキーワードの動作は、検証対象のインスタンス位置に適用される隣接キーワードの注釈結果に依存します。具体的には、「prefixItems」、「items」、「contains」の注釈が、「unevaluatedItems」キーワードに隣接している場合に生成されます。これらの3つの注釈、および「unevaluatedItems」は、隣接するすべてのインプレース適用キーワード(セクション10.2)からも生成される可能性があります。これには、このドキュメントで定義されているインプレース適用キーワードが含まれますが、これらに限定されません。
関連する注釈が存在しない場合、「unevaluatedItems」サブスキーマは配列内のすべての位置に適用されなければなりません。関連する注釈のいずれかからブール値のtrueが返された場合、「unevaluatedItems」は無視されなければなりません。それ以外の場合、サブスキーマは、「prefixItems」の最大のアノテーション値よりも大きいインデックスに適用されなければなりません。ただし、この値は「contains」のどのアノテーション値にも含まれません。
これは、「prefixItems」、「items」、「contains」、およびすべてのインプレース・アプライケータが、このキーワードが評価される前に評価されなければならないことを意味します。拡張キーワードの作成者は、このキーワードの後に​​評価される必要のあるインプレース・アプライケータを定義してはなりません。
「unevaluatedItems」サブスキーマがインスタンス配列内のいずれかの位置に適用されると、「items」の動作と同様に、ブール値のtrueというアノテーション結果が生成されます。このアノテーションは、親スキーマの「unevaluatedItems」の動作に影響を与えます。
このキーワードを省略した場合、空のスキーマと同じアサーション動作になります。
11.3. unevaluatedProperties
「unevaluatedProperties」の値は、有効なJSONスキーマでなければなりません。
このキーワードの動作は、検証対象のインスタンスの場所に適用される隣接キーワードのアノテーション結果に依存します。具体的には、「properties」、「patternProperties」、「additionalProperties」のアノテーションです。これらのアノテーションは、「unevaluatedProperties」キーワードに隣接している場合に生成されます。これらの3つのアノテーションと「unevaluatedProperties」は、隣接するすべてのインプレース・アプライケータ(セクション10.2)キーワードからも生成されます。これには、このドキュメントで定義されているインプレース・アプライケータが含まれますが、これらに限定されません。
「unevaluatedProperties」による検証は、検証対象のインスタンスの場所に適用される「properties」、「patternProperties」、「additionalProperties」、または「unevaluatedProperties」のアノテーション結果に含まれないインスタンス名の子値にのみ適用されます。
これらのプロパティすべてについて、子インスタンスが「unevaluatedProperties」スキーマに対して検証に合格すれば、検証は成功します。
これは、「properties」、「patternProperties」、「additionalProperties」、およびすべてのインプレース・アプライケータが、このキーワードが評価される前に評価されなければならないことを意味します。拡張キーワードの作成者は、このキーワードの後に​​評価される必要のあるインプレース・アプライケータを定義してはなりません。
このキーワードの注釈結果は、このキーワードのサブスキーマによって検証されたインスタンス・プロパティ名のセットです。この注釈は、親スキーマにおける「unevaluatedProperties」の動作に影響を与えます。
このキーワードを省略した場合、空のスキーマと同じアサーション動作になります。
12. 出力フォーマット
JSONスキーマはプラットフォーム非依存として定義されています。そのため、プラットフォーム間の互換性を高めるために、実装は標準的な検証出力フォーマットに準拠する必要があります。このセクションでは、コンシューマーが検証結果を正しく解釈するために必要な最小限の要件について説明します。
12.1.フォーマット
JSONスキーマの出力は、セクション4.2.1で説明されているJSONスキーマデータインスタンスモデルを使用して定義されます。実装は、それぞれの言語やプラットフォームのサポートに応じて、この定義から逸脱する場合がありますが、出力はシリアライゼーションなどの手段によって、ここで定義されているJSONフォーマットに変換可能であることが推奨されます。
12.2. 出力フォーマット
この仕様では、4つの出力フォーマットを定義します。各フォーマットの要件については、「出力構造」セクションを参照してください。
Flag - 検証結果全体を示すブール値で、詳細情報は含まれません。
Basic - 検証情報をフラットなリスト構造で提供します。
Detailed - スキーマの構造に基づいた、簡潔な階層構造で検証情報を提供します。
Verbose - スキーマの構造に完全に一致する、非簡潔な階層構造で検証情報を提供します。
実装は、「flag」、「basic」、「detailed」フォーマットのうち少なくとも1つを提供する必要があり、「verbose」フォーマットを提供してもよいでしょう。 「詳細」または「冗長」形式のいずれかを提供する場合、必ず「フラグ」形式も提供しなければなりません。実装は、サポートする形式をドキュメントに明記する必要があります。
12.3. 最小限の情報
単純な「フラグ」出力に加えて、スキーマまたはインスタンスのデバッグに役立つ追加情報があると便利です。各サブ結果には、少なくともこのセクションに記載されている情報が含まれている必要があります。
これらのコンポーネントすべてを含む単一のオブジェクトは、出力単位とみなされます。
実装は、追加情報を提供することもできます。
12.3.1. キーワードの相対位置
検証パスに続く検証キーワードの相対位置。値はJSONポインタとして表現する必要があり、「$ref」や「$dynamicRef」などの参照渡し適用子を含める必要があります。
code:relative
/properties/width/$ref/minimum
このポインタは、参照渡しの適用キーワードが含まれているため、通常の JSON ポインタ処理では解決できない場合があります。
この情報の JSON キーは「keywordLocation」です。
12.3.2. キーワードの絶対位置
検証対象のキーワードの絶対的な参照解除された位置。値は、関連するスキーマ リソースの正規 URI と JSON ポインタ フラグメントを使用した完全な URI として表現する必要があり、非終端パス コンポーネントとして「$ref」や「$dynamicRef」などの参照渡し適用キーワードを含めてはなりません。ただし、エラーまたは注釈がそのキーワードに関するものである場合(解決できない参照など)、末尾にこれらのキーワードを含めても構いません。ここでいう「絶対」とは、RFC 3986 の「絶対 URI」(スキーマは含まれるがフラグメントは含まれない)ではなく、「絶対ファイルシステム パス」(完全な位置)という意味です。キーワードの絶対位置には、キーワードを識別するためのフラグメントが含まれます。
code:absolute
https://example.com/schemas/common#/$defs/count/minimum
この情報は、動的スコープが参照を渡さなかった場合、またはスキーマが「$id」として絶対URIを宣言していない場合にのみ省略できます。
この情報のJSONキーは「absoluteKeywordLocation」です。
12.3.3. インスタンスの場所
検証対象のインスタンス内におけるJSON値の場所。値はJSONポインタとして表現する必要があります。
この情報のJSONキーは「instanceLocation」です。
12.3.4. エラーまたは注釈
検証によって生成されたエラーまたは注釈。
エラーの場合、メッセージの具体的な文言はこの仕様では定義されていません。実装側で提供する必要があります。
注釈の場合、注釈を生成する各キーワードは、その形式を指定します。デフォルトでは、キーワードの値です。
検証失敗時のJSONキーは「error」、検証成功時のJSONキーは「annotation」です。
12.3.5.ネストされた結果
2つの階層構造において、このプロパティにはネストされたエラーと注釈が格納されます。
検証失敗時のネストされた結果のJSONキーは「errors」、検証成功時のネストされた結果のJSONキーは「annotations」です。ネストされた結果を持つキーワードには、ローカルなエラーや注釈も含まれる可能性があるため、複数形であることに注意してください。
12.4. 出力構造
出力は、「valid」という名前のブール型プロパティを含むオブジェクトでなければなりません。結果に関する追加情報が必要な場合は、出力には以下で説明する「errors」または「annotations」も含まれていなければなりません。
「valid」 - 検証全体の成功または失敗を示すブール値
「errors」 - 検証失敗によって生成されたエラーまたは注釈の集合
「annotations」 - 検証成功によって生成されたエラーまたは注釈の集合
これらの例では、以下のスキーマとインスタンスを使用します。
code:example.json
{
"$id": "https://example.com/polygon",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"point": {
"type": "object",
"properties": {
"x": { "type": "number" },
"y": { "type": "number" }
},
"additionalProperties": false,
"required": "x", "y"
}
},
"type": "array",
"items": { "$ref": "#/$defs/point" },
"minItems": 3
}
[
{
"x": 2.5,
"y": 1.3
},
{
"x": 1,
"z": 6.7
}
]
このインスタンスは検証に失敗し、エラーが発生しますが、アノテーションを生成するスキーマを渡す例を推測するのは容易です。
具体的には、以下のエラーが発生します。
2番目のオブジェクトに「y」プロパティがありません。
2番目のオブジェクトに許可されていない「z」プロパティがあります。
オブジェクトは2つしかありませんが、3つ必要です。
これらの例に示されているエラーメッセージの文言は、この仕様の要件ではありません。実装は、対象ユーザーに合わせてエラーメッセージを作成するか、ユーザーが独自のメッセージを作成できるテンプレートメカニズムを提供する必要があります。
12.4.1. フラグ
最も単純なケースでは、「valid」プロパティのブール値の結果を満たすだけで十分です。
code:flag.json
{
"valid": false
}
この形式ではエラーや注釈が返されないため、実装では、結果が判明次第、失敗または成功を返すショートサーキットロジックを使用することを推奨します。例えば、「anyOf」キーワードに5つのサブスキーマが含まれており、2番目のサブスキーマが成功した場合、残りの3つをチェックする必要はありません。ロジックは単純に成功を返すだけで済みます。
12.4.2. 基本
「基本」構造は、出力ユニットのフラットなリストです。
code:basic.json
{
"valid": false,
"errors": [
{
"keywordLocation": "",
"instanceLocation": "",
"error": "A subschema had errors."
},
{
"keywordLocation": "/items/$ref",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point",
"instanceLocation": "/1",
"error": "A subschema had errors."
},
{
"keywordLocation": "/items/$ref/required",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point/required",
"instanceLocation": "/1",
"error": "Required property 'y' not found."
},
{
"keywordLocation": "/items/$ref/additionalProperties",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point/additionalProperties",
"instanceLocation": "/1/z",
"error": "Additional property 'z' found but was invalid."
},
{
"keywordLocation": "/minItems",
"instanceLocation": "",
"error": "Expected at least 3 items but found 2"
}
]
}
12.4.3. Detailed(詳細)
「Detailed(詳細)」構造はスキーマに基づいており、人間と機械の両方にとって読みやすい構造になっています。このように構造を整理することで、エラー間の関連性がより明確になります。例えば、「基本」構造では、欠落している「y」プロパティと余分な「z」プロパティがインスタンス内の同じ場所から発生しているという事実はすぐには分かりません。階層構造では、相関関係をより容易に特定できます。
結果オブジェクトの構築には、以下のルールが適用されます。
すべてのアプリケータキーワード(「*Of」、「$ref」、「if」、「then」、「else」など)にはノードが必要です。
子ノードを持たないノードは削除されます。
子ノードを1つだけ持つノードは、その子ノードに置き換えられます。
分岐ノードには、エラーメッセージや注釈は必要ありません。
code:ex.json
{
"valid": false,
"keywordLocation": "",
"instanceLocation": "",
"errors": [
{
"valid": false,
"keywordLocation": "/items/$ref",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point",
"instanceLocation": "/1",
"errors": [
{
"valid": false,
"keywordLocation": "/items/$ref/required",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point/required",
"instanceLocation": "/1",
"error": "Required property 'y' not found."
},
{
"valid": false,
"keywordLocation": "/items/$ref/additionalProperties",
"absoluteKeywordLocation":
"https://example.com/polygon#/$defs/point/additionalProperties",
"instanceLocation": "/1/z",
"error": "Additional property 'z' found but was invalid."
}
]
},
{
"valid": false,
"keywordLocation": "/minItems",
"instanceLocation": "",
"error": "Expected at least 3 items but found 2"
}
]
}
12.4.4. Verbose(詳細出力)
「Verbose(詳細出力)」構造は、スキーマと完全に一致する階層構造です。この構造は、エラーの発生箇所が重要なフォーム生成や検証において活用されます。
この構造と「詳細」構造の主な違いは、すべての結果が返される点です。これには、通常は削除されるサブスキーマの検証結果(例えば、検証失敗の注釈、notキーワード内の検証成功など)も含まれます。そのため、各ノードには、そのノードの検証結果を示すvalidプロパティを持たせることを推奨します。
この出力構造は非常に大きくなる可能性があるため、ここでは簡潔にするために、より小さな例を示します。上記の例の完全な出力構造のURIは、https://json-schema.org/draft/2020-12/output/verbose-example です。
code:verbose-example.json
// schema
{
"$id": "https://example.com/polygon",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"validProp": true,
},
"additionalProperties": false
}
// instance
{
"validProp": 5,
"disallowedProp": "value"
}
// result
{
"valid": false,
"keywordLocation": "",
"instanceLocation": "",
"errors": [
{
"valid": true,
"keywordLocation": "/type",
"instanceLocation": ""
},
{
"valid": true,
"keywordLocation": "/properties",
"instanceLocation": ""
},
{
"valid": false,
"keywordLocation": "/additionalProperties",
"instanceLocation": "",
"errors": [
{
"valid": false,
"keywordLocation": "/additionalProperties",
"instanceLocation": "/disallowedProp",
"error": "Additional property 'disallowedProp' found but was invalid."
}
]
}
]
}
12.4.5. 出力検証スキーマ
利便性を考慮し、実装によって生成された出力を検証するためのJSONスキーマが提供されています。そのURIは、https://json-schema.org/draft/2020-12/output/schema です。
13. セキュリティに関する考慮事項
スキーマとインスタンスはどちらもJSON値です。そのため、RFC 8259 RFC 8259 で定義されているすべてのセキュリティに関する考慮事項が適用されます。
インスタンスとスキーマは、信頼できない第三者によって作成され、公開インターネットサーバーにデプロイされることがよくあります。バリデーターは、スキーマに対する解析と検証が過剰なシステムリソースを消費しないように注意する必要があります。バリデーターは無限ループに陥ってはなりません。
悪意のある第三者が、実装に非常に大きな値のコピーをアノテーションとして繰り返し収集させる可能性があります。実装は、このようなシナリオにおいてシステムリソースの過剰な消費を防ぐ必要があります。
サーバーは、悪意のある第三者が既存のスキーマの機能を変更できないように、既存のスキーマと類似した「$id」を持つスキーマをアップロードできないようにする必要があります。
個々のJSONスキーマ語彙にも、それぞれ独自のセキュリティ上の考慮事項が存在する可能性があります。詳細については、それぞれの仕様を参照してください。
スキーマ作成者は、「$comment」の内容に注意を払う必要があります。悪意のある実装は、仕様に違反してエンドユーザーに「$comment」を表示したり、そのような動作が想定されているにもかかわらず「$comment」を削除しなかったりする可能性があるためです。
悪意のあるスキーマ作成者は、「$comment」内に実行可能コードやその他の危険なコンテンツを埋め込む可能性があります。実装は、「$comment」の内容を解析したり、それに基づいて何らかのアクションを実行したりしてはなりません。
14. IANAに関する考慮事項
14.1. application/schema+json
JSONスキーマの提案されているMIMEメディアタイプは、以下のように定義されています。
タイプ名: application
サブタイプ名: schema+json
必須パラメータ: 該当なし
エンコーディングに関する考慮事項: エンコーディングに関する考慮事項は、「application/json」メディアタイプで指定されているものと同じです。 JSON RFC 8259 を参照してください。
セキュリティに関する考慮事項:上記のセクション 13 を参照してください。
相互運用性に関する考慮事項:上記のセクション 6.2、6.3、および 6.4 を参照してください。
フラグメント識別子に関する考慮事項:セクション 5 を参照してください。
14.2. application/schema-instance+json
JSON スキーマ固有のメディアタイプを必要とする JSON スキーマインスタンスの提案される MIME メディアタイプは、以下のように定義されます。
タイプ名: application
サブタイプ名: schema-instance+json
必須パラメータ: 該当なし
エンコーディングに関する考慮事項: エンコーディングに関する考慮事項は、「application/json」メディアタイプで指定されているものと同じです。JSON RFC 8259 を参照してください。
セキュリティに関する考慮事項:上記のセクション 13 を参照してください。
相互運用性に関する考慮事項:上記のセクション 6.2、6.3、および 6.4 を参照してください。
フラグメント識別子に関する考慮事項:セクション 5 を参照してください。
15. 参考文献
15.1. 規範的参考文献
RFC 2119
Bradner, S.、「RFCにおける要求レベルを示すためのキーワード」、BCP 14、RFC 2119、DOI 10.17487/RFC2119、1997年3月、<https://www.rfc-editor.org/info/rfc2119 >。
RFC 3986
Berners-Lee, T.、Fielding, R.、およびL. Masinter、「Uniform Resource Identifier (URI): 汎用構文」、STD 66、RFC 3986、DOI 10.17487/RFC3986、2005年1月、<https://www.rfc-editor.org/info/rfc3986 >。
RFC 6839
T. Hansen および A. Melnikov、「追加のメディアタイプ構造化構文サフィックス」、RFC 6839、DOI 10.17487/RFC6839、2013年1月、<https://www.rfc-editor.org/info/rfc6839 >。
RFC 6901
P. Bryan 編、K. Zyp および M. Nottingham 編、「JavaScriptオブジェクト表記(JSON)ポインタ」、RFC 6901、DOI 10.17487/RFC6901、2013年4月、<https://www.rfc-editor.org/info/rfc6901 >。
RFC 8259
Bray, T. 編、「JavaScript Object Notation (JSON) データ交換フォーマット」、STD 90、RFC 8259、DOI 10.17487/RFC8259、2017年12月、<https://www.rfc-editor.org/info/rfc8259 >。
W3C.REC-ldp-20150226
Speicher, S.、Arwe, J.、A. Malhotra、「Linked Data Platform 1.0」、World Wide Web Consortium勧告REC-ldp-20150226、2015年2月26日、<https://www.w3.org/TR/2015/REC-ldp-20150226 >。
ECMA262
「ECMA-262 第11版仕様書」、2020年6月、<https://www.ecma-international.org/ecma-262/11.0/index.html >。
15.2. 参考文献
RFC 6596
M. Ohye および J. Kupke、「正規リンク関係」、RFC 6596、DOI 10.17487/RFC6596、2012年4月、<https://www.rfc-editor.org/info/rfc6596 >。
RFC 7049
C. Bormann および P. Hoffman、「簡潔バイナリオブジェクト表現 (CBOR)」、RFC 7049、DOI 10.17487/RFC7049、2013年10月、<https://www.rfc-editor.org/info/rfc7049 >。
RFC 7231
R. Fielding 編、J. Reschke 編、「ハイパーテキスト転送プロトコル (HTTP/1.1): セマンティクスとコンテンツ」、RFC 7231、DOI 10.17487/RFC7231、2014年6月、<https://www.rfc-editor.org/info/rfc7231 >。
RFC 8288
Nottingham, M.、「Webリンク」、RFC 8288、DOI 10.17487/RFC8288、2017年10月、<https://www.rfc-editor.org/info/rfc8288 >。
W3C.WD-fragid-best-practices-20121025
Tennison, J.、「フラグメント識別子とメディアタイプ定義のベストプラクティス」、World Wide Web Consortium WD WD-fragid-best-practices-20121025、2012年10月25日、<https://www.w3.org/TR/2012/WD-fragid-best-practices-20121025 >。
json-schema-validation
A. Wright、H. Andrews、B. Hutton、「JSONスキーマ検証:JSONの構造検証のための語彙」、作業中、インターネットドラフト、draft-bhutton-json-schema-validation-01、2022年6月、<https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-01 >。
json-hyper-schema
H. Andrews、A. Wright、「JSONハイパースキーマ:JSONのハイパーメディア注釈のための語彙」、作業中、インターネットドラフト、draft-handrews-json-schema-hyperschema-02、2017年11月、<https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-hyperschema-02 >。
xml-names
Bray, T. 編、Hollander, D. 編、Layman, A. 編、R. Tobin 編、「XML 1.1 における名前空間(第 2 版)」、2006 年 8 月、<http://www.w3.org/TR/2006/REC-xml-names11-20060816 >。
付録A.スキーマ識別例
以下のスキーマでは、「$id」がルートスキーマと様々なサブスキーマを識別するために使用され、「$anchor」がプレーンネームフラグメント識別子を定義するために使用されています。
code:example.json
{
"$id": "https://example.com/root.json",
"$defs": {
"A": { "$anchor": "foo" },
"B": {
"$id": "other.json",
"$defs": {
"X": { "$anchor": "bar" },
"Y": {
"$id": "t/inner.json",
"$anchor": "bar"
}
}
},
"C": {
"$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f"
}
}
}
以下のURIエンコードされたJSON Pointer RFC 6901(ルートスキーマからの相対パス)にあるスキーマは、以下のベースURIを持ち、上記のセクション5および9.2.1に従って、リストされている任意のURIによって識別可能です。
# (ドキュメントルート) 正規URI(およびベースURI) https://example.com/root.json
正規リソースURIとポインタフラグメント https://example.com/root.json#
#/$defs/A ベースURI https://example.com/root.json
正規リソースURIとプレーンフラグメント https://example.com/root.json#foo
正規リソースURIとポインタフラグメント https://example.com/root.json#/$defs/A
#/$defs/B 正規URI(およびベースURI) https://example.com/other.json
正規リソースURIとポインタフラグメント https://example.com/other.json#
親リソース(root.json)のベースURIとフラグメント https://example.com/root.json#/$defs/B
#/$defs/B/$defs/X ベースURI https://example.com/other.json
正規リソースURIとプレーンフラグメント https://example.com/other.json#bar
正規リソースURIとポインタフラグメント https://example.com/other.json#/$defs/X
親リソース(root.json)のベースURIとフラグメント https://example.com/root.json#/$defs/B/$defs/X
#/$defs/B/$defs/Y 正規(およびベース)URI https://example.com/t/inner.json
正規URIとプレーンフラグメント https://example.com/t/inner.json#bar
正規URIとポインタフラグメント https://example.com/t/inner.json#
親リソース(other.json)のベースURIとフラグメント https://example.com/other.json#/$defs/Y
(root.json) リソースとフラグメント https://example.com/root.json#/$defs/B/$defs/Y
#/$defs/C 正規URI(およびベースURI) urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f
正規URIとポインタフラグメント urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#
囲んでいる(root.json)リソースとフラグメントのベースURI https://example.com/root.json#/$defs/C
注:URIのフラグメント部分自体が正規URIか非正規URIかを決定するわけではありません。フラグメントを含む完全なURIの一部として使用されるベースURIが、結果として得られるURIの正規性を決定します。完全なURI。複数の「正規」URI?これは混乱を招く可能性があることを認識しており、詳細については、JSONポインタフラグメントと埋め込みスキーマリソース(セクション9.2.1)にあるCREFを参照してください。
付録B. スキーマ文書と参照の操作
参照(「$ref」)の出現場所や方法に基づいてスキーマ文書を再構成するための様々なツールが開発されています。この付録では、どのユースケースと操作がこの仕様に準拠しているかについて説明します。
B.1. スキーマリソースを単一文書にまとめる
一緒に使用することを目的とした一連のスキーマリソースは、それぞれを個別のスキーマ文書にまとめることも、すべて同じスキーマ文書にまとめることも、あるいはその中間の任意の粒度で文書をグループ化することも可能です。
様々な種類の参照削除を実行するためのツールが数多く存在します。一般的な例としては、すべての参照をそのファイル内で解決できる単一ファイルを作成することが挙げられます。これは通常、配布を簡素化するため、あるいはJSONスキーマライブラリの様々な呼び出しにおいて多数のリソースを追跡・ロードする必要がないようにコーディングを簡素化するために行われます。
この変換は、すべての静的参照(例:「$ref」)が、正規リソースURIをベースとするURIに解決されるURI参照を使用し、かつすべてのスキーマリソースのルートスキーマに「$id」として絶対URIが設定されている限り、安全かつ可逆的に実行できます。
これらの条件が満たされている場合、各外部リソースは「$defs」の下にコピーできます。この際、リソースのスキーマオブジェクト間の参照は壊れず、検証結果や注釈結果も一切変更されません。「$defs」の下にあるスキーマ名は、それぞれ一意であれば、埋め込みリソースの正規URIには含まれないため、動作に影響を与えません。
B.2. 参照の削除は必ずしも安全ではない
すべての参照を削除して単一のスキーマ文書を作成しようとしても、必ずしも元の形式と全く同じ動作をするスキーマが生成されるとは限りません。
「$ref」は他のキーワードと同様に扱われるようになり、同じスキーマオブジェクト内で他のキーワードも使用できるようになったため、あらゆる場合において非再帰的な「$ref」の削除を完全にサポートするには、比較的複雑なスキーマ操作が必要になる場合があります。安全な「$ref」削除変換のセットを決定または提供することは、スキーマ構造だけでなく使用目的にも依存するため、この仕様の範囲外です。
付録C. 再帰的なスキーマ拡張の例
単純な再帰ツリー構造を記述する以下の2つのスキーマを考えてみましょう。ツリー内の各ノードは、任意の型の「data」フィールドを持つことができます。最初のスキーマは、他のインスタンスプロパティを許可し、無視します。2番目のスキーマはより厳格で、「data」と「children」プロパティのみを許可します。「data」が「daat」と誤記されたインスタンスの例も示されています。
code:example.json
// tree schema, extensible
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/tree",
"$dynamicAnchor": "node",
"type": "object",
"properties": {
"data": true,
"children": {
"type": "array",
"items": {
"$dynamicRef": "#node"
}
}
}
}
// strict-tree schema, guards against misspelled properties
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/strict-tree",
"$dynamicAnchor": "node",
"$ref": "tree",
"unevaluatedProperties": false
}
// instance with misspelled field
{
"children": { "daat": 1 }
}
これら2つのスキーマを読み込むと、それぞれに「node」という名前の「$dynamicAnchor」(# は付いていません。これは単なる名前です)が存在することがわかります。その結果、以下の完全なスキーマURIが生成されます。
「https://example.com/tree#node 」
「https://example.com/strict-tree#node 」
さらに、JSONスキーマの実装では、これらのフラグメントが「$dynamicAnchor」によって作成されたという事実が記録されます。
インスタンスに「strict-tree」スキーマを適用すると、「$ref」をたどって「tree」スキーマにアクセスし、その「children」サブスキーマを調べ、「items」サブスキーマ内で「#node」への「$dynamicRef」を見つけます(# はURIフラグメント構文を表します)。この参照は「https://example.com/tree#node 」に解決されます。これは「$dynamicAnchor」によって作成されたフラグメントを含むURIです。したがって、参照をたどる前に動的スコープを調べる必要があります。
この時点で、動的パスは「#/$ref/properties/children/items/$dynamicRef」であり、動的スコープは(最外側のスコープから最内側のスコープまで)以下のようになっています。
1. 「https://example.com/strict-tree# 」
2. 「https://example.com/tree# 」
3. 「https://example.com/tree#/properties/children 」
4. 「https://example.com/tree#/properties/children/items 」
ここでは、スキーマリソース内のどこにでも定義できるプレーンネームフラグメントを探しているため、JSONポインタフラグメントはこのチェックには関係ありません。つまり、これらのフラグメントを削除し、連続する重複を排除することで、以下の結果が得られます。
1. 「https://example.com/strict-tree 」
2. 「https://example.com/tree 」
この場合、最外側のリソースには、「$dynamicAnchor」で定義された「node」フラグメントも存在します。したがって、「$dynamicRef」を「https://example.com/tree#node 」に解決する代わりに、「https://example.com/strict-tree#node 」に解決します。
こうすることで、「tree」スキーマの再帰処理は「strict-tree」のルートまで再帰的に行われ、インスタンスのルートにのみ「strict-tree」を適用し、インスタンスの子要素には「tree」を適用するという処理は行われません。
この例では、両方の「$dynamicAnchor」がそれぞれのスキーマ、具体的にはリソースルートスキーマの同じ場所に存在しています。プレーンネームフラグメントはJSON構造に依存しないため、ノードスキーマオブジェクトの一方または両方を「$defs」の下に移動しても同様に機能します。動的参照の解決方法を決定するのは、JSON構造内の相関関係ではなく、一致する「$dynamicAnchor」の値です。
付録D. 語彙の扱い方
D.1. 語彙およびメタスキーマ作成者のためのベストプラクティス
語彙作成者は、語彙が広く利用されることを想定しており、他の語彙と組み合わせる可能性がある場合、キーワード名の衝突を避けるよう注意する必要があります。JSON Schemaには正式な名前空間システムは提供されていませんが、キーワード名に制約もないため、様々な名前空間方式が許容されます。
語彙は、他の語彙のキーワードの動作に関して、そのキーワードの動作を定義したり、他の語彙のキーワードを、許容値の範囲を制限または拡張して使用したりするなど、相互に拡張して構築することができます。このような語彙の再利用によって、必ずしも基となる語彙と互換性のある新しい語彙が作成されるとは限りません。語彙作成者は、どの程度の互換性が期待されるのかを明確に文書化する必要があります。
メタスキーマの作成者は、同じキーワードに対して構文や意味が矛盾する複数の語彙を結合するために「$vocabulary」を使用すべきではありません。意味の矛盾は一般的にスキーマ検証では検出できないため、実装側でそのような矛盾を検出することは想定されていません。矛盾する語彙が宣言された場合、結果として生じる動作は未定義です。
語彙の作成者は、語彙のキーワードの想定される使用法を検証するメタスキーマを独自に提供すべきです。このようなメタスキーマは、追加のキーワードを禁止すべきではなく、コア語彙のキーワードを禁止してはなりません。
メタスキーマの作成者は、各語彙のメタスキーマを参照する際に「allOf」(セクション10.2.1.1)キーワードを使用することを推奨しますが、特定のユースケースにおいては、メタスキーマを構築するための他のメカニズムが適切な場合もあります。
メタスキーマの再帰的な性質により、「$dynamicAnchor」と「$dynamicRef」キーワードは、既存のメタスキーマを拡張する際に特に有用です。これは、Validationメタスキーマを拡張するJSON Hyper-Schemaメタスキーマの例からも明らかです。
メタスキーマは、宣言された語彙に関連付けられたメタスキーマが記述する内容を超えて、どの語彙にも存在しないキーワードを記述するなど、追加の制約を課すことができます。これにより、語彙のサブセットへの使用を制限したり、再利用を意図しないローカルで定義されたキーワードを検証したりすることが可能になります。
ただし、メタスキーマは、宣言する語彙と矛盾してはなりません。例えば、語彙が想定するJSON型とは異なる型を要求するなどです。その結果、動作は未定義となります。
任意の実装における語彙のサポートをテストする必要のない、ローカルでの使用を目的としたメタスキーマでは、「$vocabulary」を完全に省略しても問題ありません。
D.2.語彙宣言を含むメタスキーマの例
このメタスキーマは、コア語彙とアプリケーター語彙、および拡張語彙を明示的に宣言し、それらのメタスキーマを「allOf」で結合しています。拡張語彙のメタスキーマは、その語彙に含まれるキーワードのみを記述しており、メインのメタスキーマ例の後に示されています。
メインのメタスキーマ例では、実装が特に複雑な「unevaluated」で始まるキーワードの使用を禁止することで、「未評価」語彙の使用を制限しています。これは、他の語彙で定義されているセマンティクスやキーワードセットを変更するものではありません。単に、このメタスキーマを使用するスキーマが「unevaluated」で始まるキーワードを使用しようとすると、このメタスキーマに対する検証に失敗するようにするためです。
最後に、このメタスキーマは、どの語彙にも含まれていないキーワード「localKeyword」の構文を記述しています。おそらく、このメタスキーマの実装者と利用者は「localKeyword」の意味を理解しているでしょう。JSON Schemaは、語彙以外でキーワードの意味を表現するメカニズムを定義していないため、特定の環境で理解される場合を除き、キーワードの意味を表現することは適切ではありません。
このメタスキーマは、汎用的に使用できるよう複数の語彙を統合しています。
code:example.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/meta/general-use-example",
"$dynamicAnchor": "meta",
"$vocabulary": {
"https://json-schema.org/draft/2020-12/vocab/core": true,
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
"https://json-schema.org/draft/2020-12/vocab/validation": true,
"https://example.com/vocab/example-vocab": true
},
"allOf": [
{"$ref": "https://json-schema.org/draft/2020-12/meta/core"},
{"$ref": "https://json-schema.org/draft/2020-12/meta/applicator"},
{"$ref": "https://json-schema.org/draft/2020-12/meta/validation"},
{"$ref": "https://example.com/meta/example-vocab"}
],
"patternProperties": {
"^unevaluated": false
},
"properties": {
"localKeyword": {
"$comment": "Not in vocabulary, but validated if used",
"type": "string"
}
}
}
このメタスキーマは、単一の拡張語彙のみを記述する。
code:example.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/meta/example-vocab",
"$dynamicAnchor": "meta",
"$vocabulary": {
"https://example.com/vocab/example-vocab": true,
},
"type": "object", "boolean",
"properties": {
"minDate": {
"type": "string",
"pattern": "\d\d\d\d-\d\d-\d\d",
"format": "date",
}
}
}
上記のように、汎用メタスキーマの「allOf」で参照される各単一語彙メタスキーマはそれぞれ対応する語彙を宣言していますが、この新しいメタスキーマではそれらを再宣言する必要があります。
コア仕様と検証仕様で定義されているすべての語彙を組み合わせた標準メタスキーマ、およびこれらの仕様とハイパースキーマ仕様で定義されているすべての語彙を組み合わせた標準メタスキーマは、さらに複雑な組み合わせを示しています。これらのメタスキーマのURIは、それぞれ検証仕様とハイパースキーマ仕様に記載されています。
汎用メタスキーマは「minDate」の構文を検証できますが、「minDate」の意味論的な意味の背後にあるロジックを定義するのは語彙です。意味論(この例では、インスタンス値はスキーマでキーワードの値として指定された日付以降でなければならない)を理解していなければ、実装は構文的な使用法しか検証できません。この場合、それは日付形式の文字列であることを検証することを意味します(検証仕様json-schema-validationで説明されているように、「format」が純粋に注釈として機能する場合でも検証されるように「pattern」を使用します)。
付録E. 参照と生成ユースケース
参照の存在は検証結果には影響を与えないことが期待されますが、コードジェネレータやUIレンダラーなどの生成ユースケースでは、参照が意味的に重要な意味を持つとみなされることがよくあります。
このようなユースケース固有のセマンティクスを明示的にするために、ベストプラクティスとしては、参照キーワード(例:「$ref」)と並行して、同じスキーマオブジェクト内で使用するアノテーションキーワードを作成することです。
例えば、コードジェネレータが参照対象を独立したクラスとして扱うべきかどうか、またそれらのクラスがどのように関連しているかを判断するための、架空のキーワードを以下に示します。この例はあくまで説明のためのものであり、機能的なコード生成キーワードを提案するものではありません。
code:example.json
{
"allOf": [
{
"classRelation": "is-a",
"$ref": "classes/base.json"
},
{
"$ref": "fields/common.json"
}
],
"properties": {
"foo": {
"classRelation": "has-a",
"$ref": "classes/foo.json"
},
"date": {
"$ref": "types/dateStruct.json",
}
}
}
ここで、このスキーマはオブジェクト指向クラスの一種を表しています。「allOf」内の最初の参照は基底クラスとして指定されています。2番目の参照にはクラス関係が割り当てられていないため、コードジェネレータは、参照が存在しないかのように、ターゲットの定義とこの定義を結合する必要があります。
プロパティを見ると、「foo」はオブジェクト構成としてフラグ付けされていますが、「date」プロパティはフラグ付けされていません。これは、独立したクラスのインスタンスではなく、サブフィールドを持つ単なるフィールドです。
この使用スタイルでは、注釈は参照と同じオブジェクト内に存在し、参照として認識できる必要があります。
付録F. 謝辞
JSON Schemaの初期ドラフト作成にご尽力いただいたGary Court、Francis Galiegue、Kris Zyp、Geraint Luffの各氏に感謝いたします。
この文書への投稿や修正にご協力いただいた、Jason Desrosiers、Daniel Perrett、Erik Wilde、Evgeny Poberezkin、Brad Bowman、Gowry Sankar、Donald Pipowitch、Dave Finlay、Denis Laxalde、Phil Sturgeon、Shawn Silverman、Karen Etheridgeの各氏に感謝いたします。
付録G. 変更履歴
このセクションは、インターネットドラフトの状態から解除される前に削除してください。
draft-bhutton-json-schema-01
「type」、「contains」、「unevaluatedProperties」、「unevaluatedItems」キーワードの説明を改善し、明確化する
「canonical URI」の様々な側面を明確化する
注釈と「additionalProperties」に関する曖昧さについてコメントを追加する
語彙は正式に定義する必要がないことを明確にする
残りのメディアタイプパラメータへの参照を削除する
複数の例を修正する
draft-bhutton-json-schema-00
埋め込みリソースの場合、「$schema」は変更される可能性があります
配列値「items」の機能は「prefixItems」になりました
「items」は以前の「additionalItems」の機能を包含します
「contains」注釈の動作、および「contains」と「unevaluatedItems」の相互作用が規定されました
動作の変更に伴い、$recursive* を $dynamic* に名称変更します
$dynamicAnchor は $anchor と同様のフラグメントを定義します
$dynamic* (以前は$recursive) は、実行時ベース URI の決定を使用しなくなりました。
複合スキーマ文書 (バンドル) と処理を定義します。
正規表現のサポートについては、ECMA-262 第 11 版を参照してください。
正規表現は Unicode をサポートする必要があります。
メディアタイプパラメータを削除します。
不明なキーワードはアノテーションとして収集されることを指定します。
「unevaluatedItems」と「unevaluatedProperties」をコアから独自の語彙に移動しました。
draft-handrews-json-schema-02
JSON 仕様を RFC 8259 に更新します。
検証仕様から「definitions」を「$defs」として移動しました。
検証仕様からアプリケータキーワードを独自の語彙に移動しました。
検証仕様から「dependencies」のスキーマ形式を「dependentSchemas」として移動しました。
アノテーションの収集を形式化しました。
推奨される出力形式を指定します。
アノテーションとアサーションの結果に基づいてキーワードの相互作用を定義します。
「unevaluatedProperties」と「unevaluatedItems」を追加しました。
定義アサーション、アプリケータ、およびアノテーションモデルにおける「$ref」の動作
「$ref」に隣接するキーワードを許可
未知のキーワードを含む「$ref」ターゲットの未定義動作に注意
主にメタスキーマ拡張のために、再帰参照を追加
形式語彙の概念と、メタスキーマによる認識方法を追加
ネットワーク取得以外の初期ベースURIに関する追加ガイダンス
「application/schema+json」に「schema」メディアタイプパラメータを許可
メディアタイプパラメータとHTTP Acceptヘッダーの説明を改善
「$id」を使用して、正規およびベース絶対URIのみを確立し、フラグメントは使用しない
プレーンネームフラグメントのみの「$id」を「$anchor」に置き換える
「$id」境界を越えるJSONポインタの動作は信頼できないことを明確に
draft-handrews-json-schema-01
このドラフトは機能変更を伴わない、純粋に明確化のためのものです
JSONスキーマの主要な用途としてアノテーションを強調
明確化ユースケースによる$id
網羅的なスキーマ識別例
「外部参照」を、実装が別のドキュメントからスキーマを認識する方法とタイミングに置き換えました。
「内部参照」を、実装が解析中にスキーマ識別子を認識する方法に置き換えました。
以前の「内部」または「外部」参照の逆参照は常に同じプロセスです。
軽微な書式改善
draft-handrews-json-schema-00
スキーマキーワード語彙の概念をより明確にする
「整数」の概念はデータモデルではなく語彙から来ていることに注意する
キーワードをアサーションまたは注釈として分類し、その一般的な動作を説明する
ブールスキーマを一般化されたアサーションの観点から説明する
「$comment」は、スキーマに関するユーザーには見えない注釈のために予約する
「$id」とフラグメントに関する記述の改善
メタスキーマを再帰参照で拡張する際の課題に注意する
「application/schema-instance+json」メディアタイプを追加する
推奨事項「プロファイル」の代わりに「スキーマ」リンク関係/パラメータを使用する
draft-wright-json-schema-01
イントロを更新しました
スキーマをブール値にできるようにしました
サブスキーマには「$schema」を使用すべきではありませんが、今後変更される可能性があります
「id」を「$id」に変更しましたすべてのコアキーワードに「$」をプレフィックスとして追加
application/schema+json のフラグメントを明確化し、形式化
JSON データモデルで表現可能な CBOR などのフォーマットへの適用可能性を注記
draft-wright-json-schema-00
JSON への参照を更新
HTTP への参照を更新
JSON ポインタへの参照を更新
「id」の動作を RFC3986 に準拠して規定
URI の語彙の使用を RFC3986 に準拠
draft-pbryan-zyp-json-ref-03 への参照を削除
「$ref」の使用をスキーマが想定される箇所に限定
「JSON Schema データモデル」の定義を追加
セキュリティに関する考慮事項を追加
「id」のサブスキーマ識別子の使用を定義
HTTP での使用に関するセクションを書き直し
rel="describedBy" および rel="profile" での使用に関するセクションを書き直し
多数の無効な記述を修正例
draft-zyp-json-schema-04
ドラフトv3から抽出。
検証キーワードを別文書に分割。
ハイパーメディアキーワードを別文書に分割。
分割後の初期ドラフト。
JSON参照、JSONポインタの使用を必須とする。
「id」の役割を定義。URI解決範囲を定義。
相互運用性に関する考慮事項を追加。
draft-zyp-json-schema-00
初期ドラフト。
著者連絡先
オースティン・ライト(編集者)
メールアドレス:aaa@bzfx.net
ヘンリー・アンドリュース(編集者)
メールアドレス:andrews_henry@yahoo.com
ベン・ハットン(編集者)
ポストマン
メールアドレス:ben@jsonschema.dev
URI:https://jsonschema.dev
グレッグ・デニス
メールアドレス:gregsdennis@yahoo.com
URI:https://github.com/gregsdennis